平面頁面應用程式

Django 內建一個可選的「平面頁面」應用程式。它讓您可以在資料庫中儲存「平面」HTML 內容,並透過 Django 的管理介面和 Python API 來處理管理工作。

平面頁面是一個具有 URL、標題和內容的物件。對於您想要儲存在資料庫中,但不希望開發自訂 Django 應用程式的單次、特殊情況頁面 (例如「關於」或「隱私權政策」頁面),可以使用它。

平面頁面可以使用自訂樣板或預設的系統級平面頁面樣板。它可以與一個或多個網站關聯。

如果您偏好將內容放在自訂樣板中,則內容欄位可以選擇性地留白。

安裝

若要安裝平面頁面應用程式,請按照下列步驟操作

  1. sites framework 新增至您的 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

有幾種方法可以在您的 URLconf 中包含平面頁面。您可以將特定路徑專用於平面頁面

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

您也可以將其設定為「萬用」模式。在這種情況下,請務必將此模式放置在其他 urlpatterns 的結尾

from django.contrib.flatpages import views

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

警告

如果您將 APPEND_SLASH 設定為 False,您必須移除萬用模式中的斜線,否則不含尾端斜線的平面頁面將不會比對到。

另一種常見設定是對有限的已知頁面使用平面頁面,並硬式編碼 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 樣板正常運作

請注意,只有在另一個檢視成功產生 404 回應之後,FlatpageFallbackMiddleware 才會介入。如果另一個檢視或中介軟體類別嘗試產生 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/default.html 呈現,但是您可以針對特定的平面頁面覆寫該樣板:在管理介面中,標題為「進階選項」的摺疊欄位集 (按一下即可展開) 包含一個用於指定樣板名稱的欄位。如果您透過 Python API 建立平面頁面,您可以將樣板名稱設定為 FlatPage 物件上的欄位 template_name

建立 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 在樣板中都標示為需要自動 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 定義的所有公開可見的 純文字頁面 (請參閱 網站 文件),並在網站地圖中建立一個項目。這些項目只包含 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",
    ),
]
回到頂端