網站地圖框架¶
Django 內建高階網站地圖產生框架,用以建立 網站地圖 XML 檔案。
概觀¶
網站地圖是您網站上的一個 XML 檔案,它會告知搜尋引擎索引器您的頁面變更頻率,以及某些頁面相對於您網站上其他頁面的「重要性」。此資訊有助於搜尋引擎索引您的網站。
Django 網站地圖框架可讓您使用 Python 程式碼表示此資訊,藉此自動化建立此 XML 檔案的流程。
它的運作方式很像 Django 的 聯合饋送框架。若要建立網站地圖,請撰寫 Sitemap
類別,並在您的 URLconf 中指向它。
安裝¶
若要安裝網站地圖應用程式,請依照下列步驟進行
將
'django.contrib.sitemaps'
新增至您的INSTALLED_APPS
設定。請確認您的
TEMPLATES
設定包含一個DjangoTemplates
後端,其APP_DIRS
選項設定為True
。它預設會在那裡,因此如果您已變更該設定,您才需要變更此設定。請確認您已安裝
網站 框架
。
(注意:網站地圖應用程式不會安裝任何資料庫表格。它之所以需要進入 INSTALLED_APPS
的唯一原因是,Loader()
範本載入器可以找到預設範本。)
初始化¶
- views.sitemap(request, sitemaps, section=None, template_name='sitemap.xml', content_type='application/xml')¶
若要在您的 Django 網站上啟用網站地圖產生功能,請將此行新增至您的 URLconf
from django.contrib.sitemaps.views import sitemap
path(
"sitemap.xml",
sitemap,
{"sitemaps": sitemaps},
name="django.contrib.sitemaps.views.sitemap",
)
這會告知 Django,當用戶端存取 /sitemap.xml
時,建立網站地圖。
網站地圖檔案的名稱並不重要,但位置很重要。搜尋引擎只會索引您網站地圖中目前 URL 層級及以下的連結。例如,如果 sitemap.xml
位於您的根目錄中,則它可以參考您網站中的任何 URL。但是,如果您的網站地圖位於 /content/sitemap.xml
,則它只能參考以 /content/
開頭的 URL。
網站地圖檢視會採用一個額外的必要引數:{'sitemaps': sitemaps}
。sitemaps
應該是一個字典,它會將簡短的區段標籤 (例如,blog
或 news
) 對應到其 Sitemap
類別 (例如,BlogSitemap
或 NewsSitemap
)。它也可以對應到 Sitemap
類別的執行個體 (例如,BlogSitemap(some_var)
)。
Sitemap
類別¶
Sitemap
類別是 Python 類別,代表您網站地圖中項目的「區段」。例如,一個 Sitemap
類別可以代表您網誌的所有項目,而另一個類別可以代表您行事曆中的所有活動。
在最簡單的情況下,所有這些區段都會被歸在一起到一個 sitemap.xml
中,但也可能使用該框架產生一個網站地圖索引,該索引會參考個別的網站地圖檔案,每個區段一個。(請參閱下方的 建立網站地圖索引。)
Sitemap
類別必須子類別化 django.contrib.sitemaps.Sitemap
。它們可以位於您程式碼庫中的任何位置。
範例¶
假設您有一個網誌系統,其中包含 Entry
模型,並且您希望您的網站地圖包含所有指向您個別網誌項目的連結。以下是您的網站地圖類別的外觀
from django.contrib.sitemaps import Sitemap
from blog.models import Entry
class BlogSitemap(Sitemap):
changefreq = "never"
priority = 0.5
def items(self):
return Entry.objects.filter(is_draft=False)
def lastmod(self, obj):
return obj.pub_date
注意
changefreq
和priority
是對應於<changefreq>
和<priority>
元素的類別屬性。它們可以變成可呼叫的函式,就像範例中的lastmod
一樣。items()
是一種方法,會傳回物件的 序列 或QuerySet
。傳回的物件將會傳遞至對應於網站地圖屬性的任何可呼叫的方法 (location
、lastmod
、changefreq
和priority
)。在此範例中沒有
location
方法,但您可以提供它以指定您的物件的 URL。預設情況下,location()
會在每個物件上呼叫get_absolute_url()
並傳回結果。
Sitemap
類別參考¶
- class Sitemap[原始碼]¶
一個
Sitemap
類別可以定義以下方法/屬性:- items[原始碼]¶
必要。 一個方法,會回傳一個物件的序列或
QuerySet
。框架不在意這些物件的類型;重要的是這些物件會被傳遞到location()
、lastmod()
、changefreq()
和priority()
方法。
- location[原始碼]¶
選用。 可以是方法或屬性。
如果它是方法,它應該回傳由
items()
回傳的給定物件的絕對路徑。如果它是屬性,它的值應該是一個字串,表示要用於
items()
回傳的每個物件的絕對路徑。在這兩種情況下,「絕對路徑」指的是不包含協定或網域的 URL。範例:
正確:
'/foo/bar/'
錯誤:
'example.com/foo/bar/'
錯誤:
'https://example.com/foo/bar/'
如果沒有提供
location
,框架會對items()
回傳的每個物件呼叫get_absolute_url()
方法。若要指定
'http'
以外的協定,請使用protocol
。
- lastmod¶
選用。 可以是方法或屬性。
如果它是方法,它應該接收一個參數,即由
items()
回傳的物件,並以datetime
的形式回傳該物件的最後修改日期/時間。如果它是屬性,它的值應該是一個
datetime
,表示items()
回傳的每個物件的最後修改日期/時間。如果網站地圖中的所有項目都有
lastmod
,則由views.sitemap()
產生的網站地圖將會有一個Last-Modified
標頭,其值等於最新的lastmod
。你可以啟用ConditionalGetMiddleware
以使 Django 適當地回應包含If-Modified-Since
標頭的要求,這將防止在網站地圖沒有變更時傳送網站地圖。
- changefreq¶
選用。 可以是方法或屬性。
如果它是方法,它應該接收一個參數,即由
items()
回傳的物件,並以字串的形式回傳該物件的變更頻率。如果它是屬性,它的值應該是一個字串,表示
items()
回傳的每個物件的變更頻率。無論你使用方法還是屬性,
changefreq
可能的值為:'always'
'hourly'
'daily'
'weekly'
'monthly'
'yearly'
'never'
- priority¶
選用。 可以是方法或屬性。
如果它是方法,它應該接收一個參數,即由
items()
回傳的物件,並以字串或浮點數的形式回傳該物件的優先順序。如果它是屬性,它的值應該是一個字串或浮點數,表示
items()
回傳的每個物件的優先順序。priority
的範例值:0.4
,1.0
。頁面的預設優先順序為0.5
。有關更多資訊,請參閱 sitemaps.org 文件。
- protocol¶
選用。
此屬性定義網站地圖中 URL 的協定 (
'http'
或'https'
)。如果未設定,則使用請求網站地圖的協定。如果網站地圖是在請求上下文之外建立的,則預設為'https'
。在 Django 5.0 中變更在較舊的版本中,在請求上下文之外建立的網站地圖的預設協定為
'http'
。
- alternates¶
選用。
一個布林值屬性。當與
i18n
結合使用時,產生的每個 URL 都會有一份替代連結清單,使用 hreflang 屬性指向其他語言版本。預設值為False
。
- x_default¶
選用。
一個布林值屬性。當
True
時,由alternates
產生的替代連結將包含一個hreflang="x-default"
後備項目,其值為LANGUAGE_CODE
。預設值為False
。
- get_latest_lastmod()[原始碼]¶
可選的。 一個方法,回傳由
lastmod
回傳的最新值。此函數用於將lastmod
屬性添加到 網站地圖索引上下文變數 中。預設情況下,
get_latest_lastmod()
會回傳如果
lastmod
是一個方法:呼叫該方法並帶入由Sitemap.items()
回傳的所有項目後,回傳的最新的lastmod
值。
- get_languages_for_item(item)[原始碼]¶
可選的。 一個方法,回傳顯示該項目的語言代碼序列。預設情況下,
get_languages_for_item()
會回傳languages
。
快捷方式¶
網站地圖框架為常見情況提供了一個便利的類別
- class GenericSitemap(info_dict, priority=None, changefreq=None, protocol=None)[原始碼]¶
django.contrib.sitemaps.GenericSitemap
類別允許您透過傳遞一個字典來建立網站地圖,該字典必須至少包含一個queryset
條目。此 queryset 將用於產生網站地圖的項目。它也可能有一個date_field
條目,指定從queryset
檢索的物件的日期欄位。這將用於lastmod
屬性和產生的網站地圖中的get_latest_lastmod()
方法。priority
、changefreq
和protocol
關鍵字引數允許為所有 URL 指定這些屬性。
範例¶
以下是使用 GenericSitemap
的 URLconf 範例
from django.contrib.sitemaps import GenericSitemap
from django.contrib.sitemaps.views import sitemap
from django.urls import path
from blog.models import Entry
info_dict = {
"queryset": Entry.objects.all(),
"date_field": "pub_date",
}
urlpatterns = [
# some generic view using info_dict
# ...
# the sitemap
path(
"sitemap.xml",
sitemap,
{"sitemaps": {"blog": GenericSitemap(info_dict, priority=0.6)}},
name="django.contrib.sitemaps.views.sitemap",
),
]
靜態視圖的網站地圖¶
您通常會希望搜尋引擎爬蟲索引既非物件詳細資訊頁面也非平面頁面的視圖。解決方案是在 items
中明確列出這些視圖的 URL 名稱,並在網站地圖的 location
方法中呼叫 reverse()
。例如
# sitemaps.py
from django.contrib import sitemaps
from django.urls import reverse
class StaticViewSitemap(sitemaps.Sitemap):
priority = 0.5
changefreq = "daily"
def items(self):
return ["main", "about", "license"]
def location(self, item):
return reverse(item)
# urls.py
from django.contrib.sitemaps.views import sitemap
from django.urls import path
from .sitemaps import StaticViewSitemap
from . import views
sitemaps = {
"static": StaticViewSitemap,
}
urlpatterns = [
path("", views.main, name="main"),
path("about/", views.about, name="about"),
path("license/", views.license, name="license"),
# ...
path(
"sitemap.xml",
sitemap,
{"sitemaps": sitemaps},
name="django.contrib.sitemaps.views.sitemap",
),
]
建立網站地圖索引¶
- views.index(request, sitemaps, template_name='sitemap_index.xml', content_type='application/xml', sitemap_url_name='django.contrib.sitemaps.views.sitemap')¶
網站地圖框架還具有建立網站地圖索引的功能,該索引會參考個別的網站地圖檔案,每個檔案對應您 sitemaps
字典中定義的每個區段。使用上的唯一區別是
您在 URLconf 中使用兩個視圖:
django.contrib.sitemaps.views.index()
和django.contrib.sitemaps.views.sitemap()
。django.contrib.sitemaps.views.sitemap()
視圖應採用section
關鍵字引數。
以下是上述範例的相關 URLconf 行
from django.contrib.sitemaps import views
urlpatterns = [
path(
"sitemap.xml",
views.index,
{"sitemaps": sitemaps},
name="django.contrib.sitemaps.views.index",
),
path(
"sitemap-<section>.xml",
views.sitemap,
{"sitemaps": sitemaps},
name="django.contrib.sitemaps.views.sitemap",
),
]
這將自動產生一個 sitemap.xml
檔案,其中會參考 sitemap-flatpages.xml
和 sitemap-blog.xml
。Sitemap
類別和 sitemaps
字典完全不會變更。
如果所有網站地圖都有由 Sitemap.get_latest_lastmod()
回傳的 lastmod
,則網站地圖索引將會有一個等於最新 lastmod
的 Last-Modified
標頭。
如果您的其中一個網站地圖的 URL 超過 50,000 個,您應該建立索引檔案。在這種情況下,Django 會自動對網站地圖進行分頁,而索引會反映這一點。
如果您未使用預設的網站地圖視圖 – 例如,如果它使用快取裝飾器包裝 – 您必須命名您的網站地圖視圖,並將 sitemap_url_name
傳遞到索引視圖
from django.contrib.sitemaps import views as sitemaps_views
from django.views.decorators.cache import cache_page
urlpatterns = [
path(
"sitemap.xml",
cache_page(86400)(sitemaps_views.index),
{"sitemaps": sitemaps, "sitemap_url_name": "sitemaps"},
),
path(
"sitemap-<section>.xml",
cache_page(86400)(sitemaps_views.sitemap),
{"sitemaps": sitemaps},
name="sitemaps",
),
]
範本客製化¶
如果您希望為您網站上提供的每個網站地圖或網站地圖索引使用不同的範本,您可以使用 URLconf 將 template_name
參數傳遞給 sitemap
和 index
視圖來指定它
from django.contrib.sitemaps import views
urlpatterns = [
path(
"custom-sitemap.xml",
views.index,
{"sitemaps": sitemaps, "template_name": "custom_sitemap.html"},
name="django.contrib.sitemaps.views.index",
),
path(
"custom-sitemap-<section>.xml",
views.sitemap,
{"sitemaps": sitemaps, "template_name": "custom_sitemap.html"},
name="django.contrib.sitemaps.views.sitemap",
),
]
這些視圖會回傳 TemplateResponse
實例,讓您可以輕鬆自訂轉譯前的回應資料。如需更多詳細資訊,請參閱 TemplateResponse 文件。
上下文變數¶
索引¶
變數 sitemaps
是一個物件列表,其中包含每個網站地圖的 location
和 lastmod
屬性。每個 URL 都會公開以下屬性
location
: 網站地圖的位置(網址和頁面)。lastmod
: 由每個網站地圖的get_latest_lastmod()
方法填入。
網站地圖¶
變數 urlset
是一個應該出現在網站地圖中的 URL 列表。每個 URL 都會公開 Sitemap
類別中定義的屬性
alternates
changefreq
item
lastmod
location
priority
當啟用 i18n
和 alternates
時,alternates
屬性才可用。它是一個包含其他語言版本的列表,包括每個 URL 的可選 x_default
回退。每個替代版本都是一個字典,其中包含 location
和 lang_code
鍵。
每個 URL 都加入了 item
屬性,以允許更靈活地自訂範本,例如 Google 新聞網站地圖。假設 Sitemap 的 items()
會傳回一個包含 publication_data
和 tags
欄位的項目列表,如下所示將會產生一個與 Google 新聞相容的網站地圖
<?xml version="1.0" encoding="UTF-8"?>
<urlset
xmlns="https://www.sitemaps.org/schemas/sitemap/0.9"
xmlns:news="https://www.google.com/schemas/sitemap-news/0.9">
{% spaceless %}
{% for url in urlset %}
<url>
<loc>{{ url.location }}</loc>
{% if url.lastmod %}<lastmod>{{ url.lastmod|date:"Y-m-d" }}</lastmod>{% endif %}
{% if url.changefreq %}<changefreq>{{ url.changefreq }}</changefreq>{% endif %}
{% if url.priority %}<priority>{{ url.priority }}</priority>{% endif %}
<news:news>
{% if url.item.publication_date %}<news:publication_date>{{ url.item.publication_date|date:"Y-m-d" }}</news:publication_date>{% endif %}
{% if url.item.tags %}<news:keywords>{{ url.item.tags }}</news:keywords>{% endif %}
</news:news>
</url>
{% endfor %}
{% endspaceless %}
</urlset>