# Django 5.2.8 documentation

# 简单页面应用

Django 自带一个可选的“简单页面”应用程序。它可以让你在数据库中存储“简单”的 HTML 内容，并通过 Django 的管理界面和 Python API 为你处理管理。

Flatpage 是一个具有 URL、标题和内容的对象。您可以将其用于一次性、特殊情况的页面，比如您希望将其存储在数据库中，但又不想开发一个定制的 Django 应用程序的页面，比如 "关于我们" 或 "隐私政策" 页面。

一个简单页面可以使用自定义模板，也可以使用系统默认的简单页面模板。它可以与一个或多个网站关联。

如果你想把你的内容放在一个自定义模板中，内容字段可以选择留空。

## 安装

要安装简单页面应用，请按照以下步骤操作：

1. 安装 `站点框架`，在 `INSTALLED_APPS` 设置中添加 `'django.contrib.sites'`，如果还没有的话。

   Also make sure you've correctly set `SITE_ID` to the ID of the site the settings file represents. This will usually be `1` (i.e. `SITE_ID = 1`), but if you're using the sites framework to manage multiple sites, it could be the ID of a different site.

2. 将 `'django.contrib.flatpages'` 添加到你的 `INSTALLED_APPS` 配置中。

那么无论是：

3. 在你的 URLconf 中添加一个条目。例如：

       urlpatterns = [
           path("pages/", include("django.contrib.flatpages.urls")),
       ]

或：

3. 将 `'django.contrib.flatpages.middleware.FlatpageFallbackMiddleware'` 添加到你的 `MIDDLEWARE` 配置中。

4. 运行命令 `manage.py migrate`。

## 工作方式

`manage.py migrate` 在数据库中创建两个表。`django_flatpage` 和 `django_flatpage_sites`。`django_flatpage` 是一个查找表，将一个 URL 映射到标题和一堆文本内容。`django_flatpage_sites` 将一个简单页面与一个网站关联起来。

### 使用 URLconf

There are several ways to include the flatpages in your URLconf. You can dedicate a particular path to flatpages:

    urlpatterns = [
        path("pages/", include("django.contrib.flatpages.urls")),
    ]

你也可以把它设置成一个“catchall”模式。在这种情况下，重要的是将该模式放在其他 urlpatterns 的最后：

    from django.contrib.flatpages import views

    # Your other patterns here
    urlpatterns += [
        re_path(r"^(?P<url>.*/)$", views.flatpage),
    ]

Warning

如果你将 `APPEND_SLASH` 设置为 `False`，你必须删除 catchall 模式中的斜杠，否则没有尾部斜杠的简单页面将不会被匹配。

Another common setup is to use flatpages for a limited set of known pages and to hardcode their URLs in the URLconf:

    from django.contrib.flatpages import views

    urlpatterns += [
        path("about-us/", views.flatpage, kwargs={"url": "/about-us/"}, name="about"),
        path("license/", views.flatpage, kwargs={"url": "/license/"}, name="license"),
    ]

The `kwargs` argument sets the `url` value used for the `FlatPage` model lookup in the flatpage view.

The `name` argument allows the URL to be reversed in templates, for example using the `url` template tag.

### 使用中间件

`FlatpageFallbackMiddleware` 可以完成所有的工作。

class FlatpageFallbackMiddleware

  每当任何 Django 应用出现 404 错误时，这个中间件都会检查简单页面数据库中所请求的 URL，作为最后的手段。具体来说，它检查给定 URL 的简单页面，其网站 ID 对应于:setting:SITE_ID 配置。

  如果它找到了一个匹配，就按照这个算法：

  - 如果简单页面有自定义模板，它就加载该模板。否则，它会加载模板 `flatpages/default.html`。

  - 它给该模板传递了一个上下文变量 `flatpage`，也就是简单页面对象。它使用 `RequestContext` 来渲染模板。

  如果产生的 URL 指向有效的简单页面，中间件只会添加尾部的斜线和重定向（通过查看 `APPEND_SLASH` 配置）。重定向是永久性的（301 状态码）。

  如果没有找到匹配的请求，则继续照常处理。

  中间件只有在 404 时才会被激活——而不是 500 或任何其他状态码的响应。

简单页面不会应用视图中间件

因为 `FlatpageFallbackMiddleware` 只有在 URL 解析失败并产生 404 之后才会应用，所以它返回的响应不会应用任何 视图中间件 方法。只有通过正常 URL 解析成功路由到视图的请求才会应用视图中间件。

注意 `MIDDLEWARE` 的顺序很重要。一般来说，你可以把 `FlatpageFallbackMiddleware` 放在列表的最后。这意味着它将在处理响应时首先运行，并确保任何其他响应处理中间件看到的是真正的简单页面响应而不是 404。

关于中间件的更多内容，请阅读 中间件文档。

确保你的 404 模板工作

Note that the `FlatpageFallbackMiddleware` only steps in once another view has successfully produced a 404 response. If another view or middleware class attempts to produce a 404 but ends up raising an exception instead, the response will become an HTTP 500 ("Internal Server Error") and the `FlatpageFallbackMiddleware` will not attempt to serve a flatpage.

## 如何添加、更改和删除简单页面

Warning

应该将添加或编辑 flatpages 的权限限制在受信任的用户上。Flatpages 是由原始 HTML 定义的，不会被 Django 进行清理。因此，恶意的 flatpage 可能会导致各种安全漏洞，包括权限升级。

### 通过管理界面

如果你已经激活了 Django 的自动管理界面，你应该会在管理索引页上看到一个“简单页面”栏目。编辑简单页面就像编辑系统中的其他对象一样。

`FlatPage` 模型有一个 `enable_comments` 字段，`contrib.flatpages` 没有使用，但对你的项目或第三方应用程序可能有用。它不会出现在管理界面中，但你可以通过为 `FlatPage` 注册一个自定义的 `ModelAdmin` 来添加它：

    from django.contrib import admin
    from django.contrib.flatpages.admin import FlatPageAdmin
    from django.contrib.flatpages.models import FlatPage
    from django.utils.translation import gettext_lazy as _

    # Define a new FlatPageAdmin
    class FlatPageAdmin(FlatPageAdmin):
        fieldsets = [
            (None, {"fields": ["url", "title", "content", "sites"]}),
            (
                _("Advanced options"),
                {
                    "classes": ["collapse"],
                    "fields": [
                        "enable_comments",
                        "registration_required",
                        "template_name",
                    ],
                },
            ),
        ]

    # Re-register FlatPageAdmin
    admin.site.unregister(FlatPage)
    admin.site.register(FlatPage, FlatPageAdmin)

### 通过 Python API

Flatpages are represented by a standard Django model, `FlatPage`. You can access flatpage objects via the Django database API.

检查是否有重复的简单页面网址。

如果你通过自己的代码来添加或修改简单页面，你很可能要检查同一站点内是否有重复的简单页面 URL。管理中使用的简单页面表单可以执行这种验证检查，可以从 `django.contrib.flatpages.forms.FlatpageForm` 中导入，并在你自己的视图中使用。

## `FlatPage` model

class models.FlatPage

### 字段

`FlatPage` objects have the following fields:

class models.FlatPage
  url

    Required. 100 characters or fewer. Indexed for faster lookups.

  title

    Required. 200 characters or fewer.

  content

    Optional (`blank=True`). `TextField` that typically, contains the HTML content of the page.

  enable_comments

    Boolean. This field is not used by `flatpages` by default and does not appear in the admin interface. Please see flatpages admin interface section for a detailed explanation.

  template_name

    Optional (`blank=True`). 70 characters or fewer. Specifies the template used to render the page. Defaults to `flatpages/default.html` if not provided.

  sites

    Many-to-many relationship to `Site`, which determines the sites the flatpage is available on.

### 方法

class models.FlatPage
  get_absolute_url()

    Returns the relative URL path of the page based on the `url` attribute.

## 简单页面模板

By default, flatpages are rendered via the template `flatpages/default.html`, but you can override that for a particular flatpage: in the admin, a collapsed fieldset titled "Advanced options" (clicking will expand it) contains a field for specifying a template name. If you're creating a flatpage via the Python API you can set the template name as the field `template_name` on the `FlatPage` object.

创建 `flatpages/default.html` 模板是你的责任；在你的模板目录下，创建一个 `flatpages` 目录，其中包含一个文件 `default.html`。

简单模板被传递一个单一的上下文变量 `flatpage`，也就是简单页面对象。

下面是一个示例 `flatpages/default.html` 模板：

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <title>{{ flatpage.title }}</title>
    </head>
    <body>
    {{ flatpage.content }}
    </body>
    </html>

由于你已经在管理页面中输入了原始 HTML，所以 `flatpage.title` 和 `flatpage.content` 都在模板中被标记为 不需要 自动 HTML 转义。

## 获取模板中的 `FlatPage` 对象列表

简单页面应用提供了一个模板标签，允许你在 当前站点 上迭代所有可用的简单应用。

和所有的自定义模板标签一样，在使用它之前，你需要 加载其自定义标签库。加载库后，你可以通过 `get_flatpages` 标签来检索当前所有的简单页面。

    {% load flatpages %}
    {% get_flatpages as flatpages %}
    <ul>
        {% for page in flatpages %}
            <li><a href="{{ page.url }}">{{ page.title }}</a></li>
        {% endfor %}
    </ul>

### 显示 `registration_required` 简单页面

默认情况下，`get_flatpages` 模板标签只显示标记为 `registration_required = False` 的页面。如果你想显示受注册保护的页面，你需要使用 `for` 子句指定一个经过认证的用户。

例如：

    {% get_flatpages for someuser as about_pages %}

如果你提供了一个匿名用户， `get_flatpages` 将与你没有提供用户的行为相同——即，它将只向你显示公共的简单页面。

### 通过基础 URL 限制简单页面

一个可选的参数，`starts_with`，可以用来限制返回的页面以特定的基本 URL 开头。这个参数可以以字符串的形式传递，也可以以一个变量的形式从上下文中解析。

例如：

    {% get_flatpages '/about/' as about_pages %}
    {% get_flatpages about_prefix as about_pages %}
    {% get_flatpages '/about/' for someuser as about_pages %}

## 与 `django.contrib.sitemaps` 整合

class FlatPageSitemap

  `sitemaps.FlatPageSitemap` 类查看所有为当前 `SITE_ID` 定义的公开可见的 `flatpages` （参见 `站点文档`），并在站点地图中创建一个条目。这些条目只包括 `location` 属性——不包括 `lastmod`、 `changefreq` 或 `priority`。

### 例如

下面是一个使用 `FlatPageSitemap` 的 URLconf 的例子：

    from django.contrib.flatpages.sitemaps import FlatPageSitemap
    from django.contrib.sitemaps.views import sitemap
    from django.urls import path

    urlpatterns = [
        # ...
        # the sitemap
        path(
            "sitemap.xml",
            sitemap,
            {"sitemaps": {"flatpages": FlatPageSitemap}},
            name="django.contrib.sitemaps.views.sitemap",
        ),
    ]