# Django 5.0.9.dev20240806133106 ドキュメント

# サイトマップ・フレームワーク

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

## 概要

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

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

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

## インストール

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

1. `'django.contrib.sitemaps'` を `INSTALLED_APPS` 設定に追加します。
2. `TEMPLATES` 設定には、`DjangoTemplates` バックエンドが含まれており、`APP_DIRS` オプションが `True` に設定されていることを確認してください。これはデフォルトで設定されているので、設定を変更していない場合は、この設定を変更する必要はありません。
3. `sites フレームワーク` がインストールされていることを確認してください。

(注意: サイトマップアプリケーションはデータベーステーブルをインストールしません。 `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 クラスです。例えば、1 つの `Sitemap` クラスはブログのすべてのエントリを表し、別のクラスはイベントカレンダー内のすべてのイベントを表すことができます。

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

`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()` はオブジェクトの sequence または `QuerySet` を返すメソッドです。返されたオブジェクトはサイトマップのプロパティに対応する呼び出し可能なメソッドに渡されます (`location`、`lastmod`、`changefreq`、`priority`)。
- `lastmod` は `datetime` を返すべきです。
- この例では `location` メソッドはありませんが、オブジェクトのURLを指定するために使用できます。デフォルトでは `location()` は各オブジェクトに対して `get_absolute_url()` を呼び出し、その結果を返します。

## `Sitemap` クラス リファレンス

class `Sitemap`

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

  `items`

    必須項目. オブジェクトの sequence または `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` として返す必要があります。

    属性であれば、その値は `items()` で返されるすべてのオブジェクトの最終更新日時を表す `datetime` である必要があります。

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

  `paginator`

    オプション。

    このプロパティは、 `items()` のための `Paginator` を返します。サイトマップを一括生成する場合は、複数の `items()` 呼び出しを避けるためにこのキャッシュされたプロパティをオーバーライドすると良いでしょう。

  `changefreq`

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

    メソッドの場合、1つの引数 (`items()` で返されるオブジェクト) を取るべきであり、そのオブジェクトの変更頻度を文字列で返すべきです。

    属性であれば、その値は `items()` が返す すべての オブジェクトの変更頻度を表す文字列でなければなりません。

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

    - `'always'`
    - `'hourly'`
    - `'daily'`
    - `'weekly'`
    - `'monthly'`
    - `'yearly'`
    - `'never'`
  `priority`

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

    メソッドであれば、1つの引数 (`items()` が返すオブジェクト) を取り、そのオブジェクトの優先順位を文字列か浮動小数点数で返します。

    属性であれば、その値は、`items()` で返される すべて のオブジェクトの優先度を表す文字列または浮動小数点数である必要があります。

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

  `protocol`

    オプション。

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

    Changed in Django 5.0:

    古いバージョンでは、リクエストのコンテキスト外に構築されたサイトマップのデフォルトプロトコルは `'http'` でした。

  `limit`

    オプション。

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

  `i18n`

    オプション。

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

  `languages`

    オプション。

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

  `alternates`

    オプション。

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

  `x_default`

    オプション。

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

  `get_latest_lastmod`()

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

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

    - `lastmod` が属性の場合: `lastmod` 。
    - `lastmod` がメソッドの場合、 `Sitemap.items()` で返されるすべてのアイテムを使用してメソッドを呼び出した結果、最新の `lastmod` が返されます。
  `get_languages_for_item`(item)
    New in Django 4.2.

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

## ショートカット

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

class `GenericSitemap`(info_dict, priority=None, changefreq=None, protocol=None)

  `django.contrib.sitemaps.GenericSitemap` クラスでは、少なくとも `queryset` エントリを含む辞書を渡すことで、サイトマップを作成できます。この `queryset` は、サイトマップのアイテムを生成するために使用されます。また、`queryset` から取得されたオブジェクトの日付フィールドを指定する `date_field` エントリを持つこともできます。これは、生成されたサイトマップの `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` 辞書で定義された各セクションごとに1つずつ、個別のサイトマップファイルを参照するサイトマップインデックスを作成する機能もあります。使用上の唯一の違いは下記です:

- URLconf で 2 つのビューを使用しています: `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 を介して `sitemap` ビューや `index` ビューに `template_name` パラメータを渡すことで指定できます:

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

### コンテキスト変数

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

### インデックス

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

- `location`: サイトマップの場所 (URLとページ)。
- `lastmod`: 各サイトマップに対して `get_latest_lastmod()` メソッドによって設定されます。

### サイトマップ

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

- `alternates`
- `changefreq`
- `item`
- `lastmod`
- `location`
- `priority`

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

各URLに `item` 属性が追加され、Google news sitemaps のようなテンプレートをより柔軟にカスタマイズできるようになりました。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="http://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>