サイトマップ・フレームワークLink to this heading

Djangoには、 sitemap XML ファイルを作成するための高レベルなサイトマップ生成フレームワークが付属しています。

概要Link to this heading

サイトマップとは、検索エンジンのインデクサーに、ページの変更頻度や、あるページがサイト内の他のページと比較してどの程度「重要」であるかを伝える、ウェブサイト上のXMLファイルのことです。この情報は、検索エンジンがあなたのサイトをインデックスするのに役立ちます。

Django サイトマップフレームワークは、この情報を Python コードで表現することで、XML ファイルの作成を自動化します。

これは Django の 配信 (syndication) フレームワーク のように動作します。サイトマップを作成するには、 Sitemap クラスを書き、 URLconf の中でそれを指定します。

インストールLink to this heading

サイトマップ アプリをインストールするには、以下の手順に従ってください。

  1. 'django.contrib.sitemaps'INSTALLED_APPS 設定に追加します。

  2. TEMPLATES 設定には、DjangoTemplates バックエンドが含まれており、APP_DIRS オプションが True に設定されていることを確認してください。これはデフォルトで設定されているので、設定を変更していない場合は、この設定を変更する必要はありません。

  3. sites フレームワーク がインストールされていることを確認してください。

(注意: サイトマップアプリケーションはデータベーステーブルをインストールしません。 INSTALLED_APPS に入れる必要があるのは、 Loader() テンプレートローダーがデフォルトのテンプレートを見つけられるようにするためです)。

初期設定Link to this heading

views.sitemap(request, sitemaps, section=None, template_name='sitemap.xml', content_type='application/xml')Link to this definition

Django サイトでサイトマップの生成を有効にするには、 URLconf に以下の行を追加します:

Code
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 は短いセクションラベル (例えば blognews) を Sitemap クラス (例えば BlogSitemapNewsSitemap) にマップする辞書です。また、 Sitemap クラスの インスタンス (例えば BlogSitemap(some_var)) にマップすることもできます。

Sitemap クラスLink to this heading

Sitemap クラスは、サイトマップ内のエントリの「セクション」を表す Python クラスです。例えば、1 つの Sitemap クラスはブログのすべてのエントリを表し、別のクラスはイベントカレンダー内のすべてのイベントを表すことができます。

最も単純なケースでは、これらのセクションはすべて1つの sitemap.xml にまとめられますが、フレームワークを使って、セクションごとに1つのサイトマップファイルを参照するサイトマップインデックスを生成することもできます。(下記の Creating a sitemap index を参照してください)。

Sitemap クラスは django.contrib.sitemaps.Sitemap のサブクラスでなければなりません。これらはコードベースのどこにあっても構いません。

Link to this heading

たとえば、 Entry モデルのブログシステムがあり、サイトマップに個々のブログエントリへのリンクをすべて含めたいとします。サイトマップクラスは次のようになります:

Code
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

備考:

  • changefreqpriority はそれぞれ <changefreq><priority> 要素に対応するクラス属性です。これらは例の lastmod のように関数として呼び出すことができます。

  • items() is a method that returns a sequence or QuerySet of objects. The objects returned will get passed to any callable methods corresponding to a sitemap property (location, lastmod, changefreq, and priority).

  • lastmoddatetime を返すべきです。

  • There is no location method in this example, but you can provide it in order to specify the URL for your object. By default, location calls get_absolute_url() on each object and returns the result.

Sitemap クラス リファレンスLink to this heading

class SitemapLink to this definition

サイトマップ Sitemap クラスは以下のメソッドや属性を定義できます:

items()Link to this definition

Required. A method that returns a sequence or QuerySet of objects. The framework doesn't care what type of objects they are; all that matters is that these objects get passed to the location, lastmod, changefreq and priority methods.

locationLink to this definition

オプション。 メソッドまたは属性のいずれか。

If it's a method, it should return the absolute path for a given object as returned by items().

If it's an attribute, its value should be a string representing an absolute path to use for every object returned by items().

どちらの場合も、「絶対パス」とは、プロトコルやドメインを含まないURLを意味します。たとえば:

  • 良い例: '/foo/bar/'

  • 悪い例: 'example.com/foo/bar/'

  • 悪い例: 'https://example.com/foo/bar/'

If location isn't provided, the framework will call the get_absolute_url() method on each object as returned by items.

'http' 以外のプロトコルを指定するには、 protocol を使用してください。

lastmodLink to this definition

オプション。 メソッドまたは属性のいずれか。

If it's a method, it should take one argument -- an object as returned by items() -- and return that object's last-modified date/time as a datetime.

If it's an attribute, its value should be a datetime representing the last-modified date/time for every object returned by items().

サイトマップ内のすべてのアイテムに lastmod がある場合、 views.sitemap() によって生成されるサイトマップには、最新の lastmod に等しい Last-Modified ヘッダーが付きます。リクエストに If-Modified-Since ヘッダーがある場合、Django が適切に応答するようにするには、 ConditionalGetMiddleware をアクティブにします。これにより、サイトマップが変更されていない場合には送信を防ぎます。

paginatorLink to this definition

オプション。

This property returns a Paginator for items(). If you generate sitemaps in a batch you may want to override this as a cached property in order to avoid multiple items() calls.

changefreqLink to this definition

オプション。 メソッドまたは属性のいずれか。

If it's a method, it should take one argument -- an object as returned by items() -- and return that object's change frequency as a string.

If it's an attribute, its value should be a string representing the change frequency of every object returned by items().

changefreq の可能な値は、メソッドの場合も属性の場合も、以下の通りです。

  • 'always'

  • 'hourly'

  • 'daily'

  • 'weekly'

  • 'monthly'

  • 'yearly'

  • 'never'

priorityLink to this definition

オプション。 メソッドまたは属性のいずれか。

If it's a method, it should take one argument -- an object as returned by items() -- and return that object's priority as either a string or float.

If it's an attribute, its value should be either a string or float representing the priority of every object returned by items().

priority の例として、0.41.0 を指定します。ページのデフォルトの優先度は 0.5 です。詳細については、sitemaps.org documentation を参照してください。

protocolLink to this definition

オプション。

この属性はサイトマップのURLのプロトコル ('http' または 'https') を定義します。設定されていない場合は、サイトマップがリクエストされたプロトコルが使用されます。サイトマップがリクエストのコンテキスト外で作成された場合、デフォルトは 'https' です。

limitLink to this definition

オプション。

この属性はサイトマップの各ページに含まれるURLの最大数を定義します。この値はデフォルト値の 50000 を超えてはいけません。これは Sitemaps protocol で許可されている上限値です。

i18nLink to this definition

オプション。

このサイトマップのURLを LANGUAGES のすべてを使用して生成するかどうかを定義するブール値の属性です。デフォルトは False です。

languagesLink to this definition

オプション。

i18n が有効のときに代替リンクを生成するために使用する 言語コードsequence。デフォルトは LANGUAGES

alternatesLink to this definition

オプション。

真偽値属性。これを i18n と併用すると、生成される各URLには他言語バージョンを指す代替リンクのリストがあり、 hreflang attribute を使用します。デフォルトは False です。

x_defaultLink to this definition

オプション。

真偽値属性です。True の場合、 alternates によって生成された代替リンクには、 hreflang="x-default" フォールバックエントリーが含まれ、その値は LANGUAGE_CODE になります。デフォルトは False です。

get_latest_lastmod()Link to this definition

オプション。 lastmod で返される最新の値を返すメソッド。この関数は、 Sitemap インデックス コンテキスト変数lastmod 属性を追加するために使用されます。

デフォルトでは、 get_latest_lastmod() は以下を返します:

  • lastmod が属性の場合:  lastmod

  • If lastmod is a method: The latest lastmod returned by calling the method with all items returned by items().

get_languages_for_item(item)Link to this definition

オプション。 アイテムが表示される言語コードのシーケンスを返すメソッド。デフォルトでは、 get_languages_for_item()languages を返します。

ショートカットLink to this heading

サイトマップフレームワークは、一般的なケースに対する便利なクラスを提供します。

class GenericSitemap(info_dict, priority=None, changefreq=None, protocol=None)Link to this definition

The django.contrib.sitemaps.GenericSitemap class allows you to create a sitemap by passing it a dictionary which has to contain at least a queryset entry. This queryset will be used to generate the items of the sitemap. It may also have a date_field entry that specifies a date field for objects retrieved from the queryset. This will be used for the lastmod attribute and get_latest_lastmod() methods in the generated sitemap.

prioritychangefreqprotocol キーワード引数を使用すると、すべてのURLに対してこれらの属性を指定できます。

カスタマイズ例Link to this heading

以下は GenericSitemap を使用した URLconf の例です:

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

静的ビューのサイトマップLink to this heading

検索エンジンのクローラに、オブジェクト詳細ページでもフラットページでもないビューをインデックスさせたいことがよくあります。その解決策は、 items にこれらのビューの URL 名を明示的に列挙し、サイトマップの location メソッドで reverse() を呼び出すことです。例えば次のようにします:

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

サイトマップインデックスを作成するLink to this heading

views.index(request, sitemaps, template_name='sitemap_index.xml', content_type='application/xml', sitemap_url_name='django.contrib.sitemaps.views.sitemap')Link to this definition

サイトマップフレームワークには、 sitemaps 辞書で定義された各セクションごとに1つずつ、個別のサイトマップファイルを参照するサイトマップインデックスを作成する機能もあります。使用上の唯一の違いは下記です:

上記の例に対する関連するURLconfの行は、次のようになります:

Code
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.xmlsitemap-blog.xml の両方が参照されます。 Sitemap クラスと sitemaps 辞書は全く変わりません。

If all sitemaps have a lastmod returned by get_latest_lastmod() the sitemap index will have a Last-Modified header equal to the latest lastmod.

サイトマップの URL が 50,000 を超える場合は、インデックスファイルを作成すべきです。この場合、 Django は自動的にサイトマップをページ分割し、インデックスに反映します。

通常のサイトマップビューを使用していない場合 (たとえば、キャッシュデコレータでラップされている場合) は、サイトマップビューに名前を付けて、インデックスビューに sitemap_url_name を渡さなければなりません:

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

テンプレートをカスタマイズするLink to this heading

サイト上で利用可能な各サイトマップやサイトマップインデックスごとに異なるテンプレートを使用したい場合は、URLconf を介して sitemap ビューや index ビューに template_name パラメータを渡すことで指定できます:

Code
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 のドキュメント を参照してください。

コンテキスト変数Link to this heading

テンプレートをカスタマイズする際に、 index()sitemap() ビューには、以下のコンテキスト変数に依存できます。

インデックスLink to this heading

変数 sitemaps は各サイトマップの locationlastmod 属性を含むオブジェクトのリストです。各URLは以下の属性を持ちます:

  • location: サイトマップの場所 (URLとページ)。

  • lastmod: 各サイトマップに対して get_latest_lastmod() メソッドによって設定されます。

サイトマップLink to this heading

変数 urlset は、サイトマップに表示されるべきURLのリストです。各URLは、 Sitemap クラスで定義された属性を公開しています。

  • alternates

  • changefreq

  • item

  • lastmod

  • location

  • priority

alternates 属性は、 i18nalternates が有効になっている場合に利用可能です。それは、各URLに対してオプションの x_default フォールバックを含む、他の言語バージョンのリストです。各代替バージョンは、locationlang_code キーを持つ辞書です。

The item attribute has been added for each URL to allow more flexible customization of the templates, such as Google news sitemaps. Assuming Sitemap's items() would return a list of items with publication_data and a tags field something like this would generate a Google News compatible sitemap:

Xml Django
<?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>