Flatpages 应用程序

Django 附带了一个可选的“Flatpages”应用程序。它允许您将“平面”HTML 内容存储在数据库中,并通过 Django 的管理界面和 Python API 为您处理管理。

Flatpage 是一个具有 URL、标题和内容的对象。将其用于一次性的特殊情况页面,例如“关于”或“隐私政策”页面,您希望将其存储在数据库中,但不想为此开发自定义 Django 应用程序。

Flatpage 可以使用自定义模板或默认的系统级 Flatpage 模板。它可以与一个或多个站点关联。

如果您希望将内容放入自定义模板,则可以将内容字段留空。

安装

要安装 Flatpages 应用程序,请执行以下步骤

  1. 通过将 'django.contrib.sites' 添加到 INSTALLED_APPS 设置(如果尚未添加),安装 sites framework

    还要确保已正确将 SITE_ID 设置为设置文件所表示的网站的 ID。这通常为 1(即 SITE_ID = 1),但如果你使用 sites framework 管理多个网站,则可能是其他网站的 ID。

  2. 'django.contrib.flatpages' 添加到 INSTALLED_APPS 设置。

然后

  1. 在 URLconf 中添加一个条目。例如

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

  1. 'django.contrib.flatpages.middleware.FlatpageFallbackMiddleware' 添加到 MIDDLEWARE 设置。
  2. 运行命令 manage.py migrate

工作原理

manage.py migrate 在数据库中创建两个表:django_flatpagedjango_flatpage_sitesdjango_flatpage 是一个查找表,它将 URL 映射到标题和大量文本内容。 django_flatpage_sites 将一个 flatpage 与一个网站关联起来。

使用 URLconf

有几种方法可以在 URLconf 中包含 flat page。你可以为 flat page 分配一个特定路径

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

你还可以将其设置为“catchall”模式。在这种情况下,将模式放在其他 urlpattern 的末尾非常重要

from django.contrib.flatpages import views

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

警告

如果您将 APPEND_SLASH 设置为 False,则必须移除 catchall 模式中的斜杠,否则不带尾部斜杠的扁平页面将无法匹配。

另一种常见设置是将扁平页面用于一组已知的页面,并硬编码 URL,这样您就可以使用 url 模板标签引用它们

from django.contrib.flatpages import views

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

使用中间件

FlatpageFallbackMiddleware 可以完成所有工作。

class FlatpageFallbackMiddleware

每次任何 Django 应用程序引发 404 错误时,此中间件都会在最后检查扁平页面数据库中请求的 URL。具体来说,它会检查具有与 SITE_ID 设置相对应的站点 ID 的给定 URL 的扁平页面。

如果它找到匹配项,则遵循此算法

  • 如果扁平页面有自定义模板,则加载该模板。否则,它将加载模板 flatpages/default.html
  • 它将一个上下文变量 flatpage 传递给该模板,该变量是扁平页面对象。它在渲染模板时使用 RequestContext

如果生成的 URL 指向有效的单页,中间件将仅添加尾部斜杠并重定向(通过查看 APPEND_SLASH 设置)。重定向是永久的(301 状态代码)。

如果找不到匹配项,请求将继续按常规方式进行处理。

中间件仅针对 404 激活,不针对 500 或任何其他状态代码的响应。

单页不适用视图中间件

由于 FlatpageFallbackMiddleware 仅在 URL 解析失败并生成 404 后才应用,因此它返回的响应将不适用任何 视图中间件 方法。只有通过正常 URL 解析成功路由到视图的请求才适用视图中间件。

请注意,MIDDLEWARE 的顺序很重要。通常,您可以在列表的末尾放置 FlatpageFallbackMiddleware。这意味着它将在处理响应时首先运行,并确保任何其他响应处理中间件看到的是实际的单页响应,而不是 404。

有关中间件的更多信息,请阅读 中间件文档

确保您的 404 模板有效

请注意,FlatpageFallbackMiddleware 仅在另一个视图成功生成 404 响应后才介入。如果另一个视图或中间件类尝试生成 404 但最终引发异常,响应将变为 HTTP 500(“内部服务器错误”),并且 FlatpageFallbackMiddleware 不会尝试提供单页。

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

警告

添加或编辑单页的权限应限制为受信任的用户。单页由原始 HTML 定义,并且未经 Django 清理。因此,恶意单页可能导致各种安全漏洞,包括权限提升。

通过管理界面

如果您已激活自动 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

class FlatPage

平面页面由一个标准的 Django 模型 表示,该模型位于 django/contrib/flatpages/models.py 中。你可以通过 Django 数据库 API 访问平面页面对象。

检查重复的平面页面 URL。

如果你通过自己的代码添加或修改平面页面,你可能希望检查同一站点内的重复平面页面 URL。管理中使用的平面页面表单执行此验证检查,并且可以从 django.contrib.flatpages.forms.FlatpageForm 导入并在你自己的视图中使用。

平面页面模板

默认情况下,flatpages 通过模板 flatpages/default.html 呈现,但您可以为特定 flatpage 覆盖它:在管理中,一个标题为“高级选项”的折叠字段集(单击将展开它)包含一个用于指定模板名称的字段。如果您通过 Python API 创建 flat page,则可以将模板名称设置为 FlatPage 对象上的字段 template_name

创建 flatpages/default.html 模板是您的责任;在您的模板目录中,创建一个包含文件 default.htmlflatpages 目录。

Flatpage 模板传递了一个单一上下文变量 flatpage,它是 flatpage 对象。

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

<!DOCTYPE html>
<html>
<head>
<title>{{ flatpage.title }}</title>
</head>
<body>
{{ flatpage.content }}
</body>
</html>

由于您已经将原始 HTML 输入到 flatpage 的管理页面中,因此 flatpage.titleflatpage.content 都被标记为不要求在模板中自动 HTML 转义

在模板中获取 FlatPage 对象的列表

flatpages 应用程序提供了一个模板标签,允许您迭代 当前站点 上所有可用的 flatpages。

与所有自定义模板标签一样,您需要在使用之前加载其自定义标签库。加载库后,您可以通过 get_flatpages 标签检索所有当前 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 flatpages

默认情况下,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(请参阅 sites 文档),并在网站地图中创建条目。这些条目仅包含 location 属性,不包含 lastmodchangefreqpriority

示例

以下是使用 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",
    ),
]
返回顶部