平面页面应用程序

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

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

平面图可以使用自定义模板或默认的系统范围的平面图模板。它可以与一个或多个站点关联。

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

安装

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

  1. 安装 sites framework 通过添加 'django.contrib.sites' 对你 INSTALLED_APPS 设置,如果还没有设置。

    还要确保您正确设置 SITE_ID 设置文件所代表的站点的ID。这通常是 1 (即 SITE_ID = 1 ),但如果您使用网站框架来管理多个网站,则它可能是不同网站的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 将平面页面与网站关联起来。

使用URLCONF

有多种方法可以将平面页面包含在您的URLinf中。您可以将特定的路径专用于平面页面::

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

您也可以将其设置为“catchall”模式。在这种情况下,将模式放在其他url模式的末尾很重要:

from django.contrib.flatpages import views

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

警告

如果你设置 APPEND_SLASHFalse 必须删除catchall模式中的斜线,否则不带尾随斜线的flatpages将不匹配。

另一种常见的设置是对有限的已知页面集使用平面页面,并在 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"),
]

kwargs 参数设置 url 用于 FlatPage 平面视图中的模型查找。

name 参数允许在模板中颠倒URL,例如使用 url 模板标签。

使用中间件

这个 FlatpageFallbackMiddleware 能做所有的工作。

class FlatpageFallbackMiddleware[源代码]

每次Django应用程序引发404错误时,此中间件都会检查Flatpages数据库中请求的URL作为最后手段。具体来说,它检查具有给定URL、与 SITE_ID 设置。

如果找到匹配项,则遵循以下算法:

  • 如果平面图具有自定义模板,则加载该模板。否则,它将加载模板 flatpages/default.html .

  • 它将该模板传递给单个上下文变量, flatpage ,它是平面页面对象。它使用 RequestContext 在呈现模板时。

中间件将只添加一个尾部斜杠和重定向(通过查看 APPEND_SLASH 设置)如果结果URL引用有效的平面图。重定向是永久性的(301状态代码)。

如果找不到匹配项,则继续照常处理请求。

中间件只被激活404秒,而不是500秒或任何其他状态代码的响应。

平面图将不应用视图中间件

因为 FlatpageFallbackMiddleware 只有在URL解析失败并生成404之后才应用,它返回的响应将不会应用任何 view middleware 方法。只有通过普通URL解析成功路由到视图的请求才应用视图中间件。

注意以下顺序: MIDDLEWARE 事项。一般来说,你可以 FlatpageFallbackMiddleware 在列表的末尾。这意味着它将在处理响应时首先运行,并确保任何其他响应处理中间件看到真正的平面响应而不是404。

有关中间件的更多信息,请阅读 middleware docs .

确保404模板正常工作

注意到 FlatpageFallbackMiddleware 只有在另一个视图成功产生404响应时才执行步骤。如果另一个视图或中间件类试图产生404,但最终引发了一个异常,响应将成为HTTP 500(“内部服务器错误”), FlatpageFallbackMiddleware 不会尝试提供平板页面。

如何添加、更改和删除平面图

警告

添加或编辑平面页面的权限应仅限于受信任的用户。平面页面由原始的HTML定义,并且 not sanitized 姜戈写的。因此,恶意的平面页面可能会导致各种安全漏洞,包括权限提升。

通过管理界面

如果您已经激活了自动Django管理界面,那么您应该在管理索引页上看到一个“flatpages”部分。在编辑系统中的任何其他对象时编辑平面图。

这个 FlatPage 模型具有 enable_comments 未被使用的字段 contrib.flatpages 但这对您的项目或第三方应用程序很有用。它不会出现在管理界面中,但您可以通过注册自定义 ModelAdmin 对于 FlatPage ::

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

平面页面由标准表示 Django model , FlatPage .您可以通过访问平面页面对象 Django database API .

检查是否存在重复的平面页面URL。

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

FlatPage 模型

class models.FlatPage

领域

FlatPage 对象具有以下字段:

class models.FlatPage
url

必需的. 100个字符或更少。为更快的查找建立索引。

title

必需的. 200个字符或更少。

content

任择 (blank=True ). TextField 它通常包含页面的HTML内容。

enable_comments

布尔。此字段未被使用 flatpages 默认情况下,不会出现在管理界面中。请参阅 flatpages admin interface section 以获取详细解释。

template_name

任择 (blank=True ). 70个字符或更少。指定用于呈现页面的模板。默认为 flatpages/default.html 如果没有提供。

sites

多对多关系, Site ,这决定了 sites 平面页面可在上使用。

方法

class models.FlatPage
get_absolute_url()

属性返回页的相对URL路径 url 属性

平面图模板

默认情况下,平面页面通过模板呈现 flatpages/default.html ,但您可以针对特定平面页面重写该内容:在管理中,标题为“高级选项”(单击将展开它)的折叠字段集包含一个用于指定模板名称的字段。如果您通过Python API创建平面页面,您可以将模板名称设置为字段 template_nameFlatPage 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.titleflatpage.content 标记为 not 要求 automatic HTML escaping 在模板中。

获取列表 FlatPage 模板中的对象

Flatpages应用程序提供了一个模板标记,允许您在 current site .

像所有自定义模板标记一样,您需要 load its custom tag library 在你能使用它之前。加载库后,可以通过 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 类查看所有公开可见的 flatpages 为当前定义 SITE_ID (见 sites documentation )并在站点地图中创建一个条目。这些条目仅包括 location 属性--不是 lastmodchangefreqpriority .

例子

下面是一个使用 FlatPageSitemap ::

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",
    ),
]