サイトマップフレームワーク—Djangoドキュメント

提供:Dev Guides
< DjangoDjango/docs/3.2.x/ref/contrib/sitemaps
移動先:案内検索

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

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

概要

サイトマップは、Webサイト上のXMLファイルであり、検索エンジンのインデクサーに、ページが変更される頻度と、特定のページがサイトの他のページと比較してどの程度「重要」であるかを通知します。 この情報は、検索エンジンがサイトのインデックスを作成するのに役立ちます。

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

これは、Djangoのシンジケーションフレームワークとほとんど同じように機能します。 サイトマップを作成するには、 Sitemap クラスを記述し、 URLconf でそれをポイントします。


インストール

サイトマップアプリをインストールするには、次の手順に従います。

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

(注:サイトマップアプリケーションはデータベーステーブルをインストールしません。 :setting: `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')

これは、クライアントが/sitemap.xmlにアクセスしたときにサイトマップを作成するようにDjangoに指示します。

サイトマップファイルの名前は重要ではありませんが、場所は重要です。 検索エンジンは、現在のURLレベル以下のサイトマップ内のリンクのみをインデックスに登録します。 たとえば、sitemap.xmlがルートディレクトリにある場合、サイト内の任意のURLを参照している可能性があります。 ただし、サイトマップが/content/sitemap.xmlにある場合は、/content/で始まるURLのみを参照できます。

サイトマップビューには、{'sitemaps': sitemaps}という追加の必須引数が必要です。 sitemapsは、短いセクションラベル(blogまたはnewsなど)をそのサイトマップクラス( [など)にマップする辞書である必要があります。 X137X]またはNewsSitemap)。 また、サイトマップクラスのインスタンスBlogSitemap(some_var)など)にマップすることもできます。


Sitemapクラス

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

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

サイトマップクラスは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を返すメソッドです。 返されたオブジェクトは、サイトマッププロパティ( locationlastmodchangefreq 、および priority )に対応する呼び出し可能なメソッドに渡されます。
  • lastmoddatetimeを返すはずです。
  • この例には location メソッドはありませんが、オブジェクトのURLを指定するためにメソッドを指定できます。 デフォルトでは、 location()は各オブジェクトでget_absolute_url()を呼び出し、結果を返します。


Sitemapクラスリファレンス

class Sitemap

Sitemapクラスは、次のメソッド/属性を定義できます。

items

必須。オブジェクトのシーケンスまたはQuerySetを返すメソッド。 フレームワークは、オブジェクトのタイプが何であるかを気にしません。 重要なのは、これらのオブジェクトが location()lastmod()changefreq()、および priority()に渡されることです。メソッド。

location

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

メソッドの場合は、 items()によって返される特定のオブジェクトの絶対パスを返す必要があります。

属性の場合、その値は、 items()によって返されるすべてのオブジェクトに使用する絶対パスを表す文字列である必要があります。

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

location が指定されていない場合、フレームワークは items()によって返される各オブジェクトでget_absolute_url()メソッドを呼び出します。

'http'以外のプロトコルを指定するには、プロトコルを使用します。

lastmod

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

メソッドの場合は、1つの引数( items()によって返されるオブジェクト)を取り、そのオブジェクトの最終変更日時をdatetimeとして返す必要があります。

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

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

paginator

オプション。

このプロパティは、 items()に対して Paginator を返します。 バッチでサイトマップを生成する場合は、複数のitems()呼び出しを回避するために、これをキャッシュプロパティとしてオーバーライドすることをお勧めします。

changefreq

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

メソッドの場合は、1つの引数( items()によって返されるオブジェクト)を取り、そのオブジェクトの変更頻度を文字列として返す必要があります。

属性の場合、その値は、 items()によって返される every オブジェクトの変更頻度を表す文字列である必要があります。

メソッドまたは属性のどちらを使用する場合でも、 changefreq に指定できる値は次のとおりです。

  • 'always'

  • 'hourly'

  • 'daily'

  • 'weekly'

  • 'monthly'

  • 'yearly'

  • 'never'

priority

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

メソッドの場合は、1つの引数( items()によって返されるオブジェクト)を取り、そのオブジェクトの優先度を文字列または浮動小数点数として返す必要があります。

属性の場合、その値は、 items()によって返されるすべてのオブジェクトの優先度を表す文字列またはfloatのいずれかである必要があります。

priority の値の例:0.41.0。 ページのデフォルトの優先度は0.5です。 詳細については、 sitemaps.orgのドキュメントを参照してください。

protocol

オプション。

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

limit

オプション。

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

i18n

オプション。

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

languages

バージョン3.2の新機能。

オプション。

i18n が有効な場合に代替リンクを生成するために使用する言語コードシーケンス。 デフォルトは:setting: `LANGUAGES` です。

alternates

バージョン3.2の新機能。

オプション。

ブール属性。 i18n と組み合わせて使用すると、生成されたURLにはそれぞれ、 hreflang属性を使用して他の言語バージョンを指す代替リンクのリストが含まれます。 デフォルトはFalseです。

x_default

バージョン3.2の新機能。

オプション。

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


ショートカット

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

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

django.contrib.sitemaps.GenericSitemap クラスを使用すると、少なくともquerysetエントリを含む必要のある辞書を渡すことでサイトマップを作成できます。 このクエリセットは、サイトマップのアイテムを生成するために使用されます。 また、querysetから取得したオブジェクトの日付フィールドを指定するdate_fieldエントリが含まれる場合もあります。 これは、生成されたサイトマップの lastmod 属性に使用されます。

prioritychangefreq 、および 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'),
]

静的ビューのサイトマップ

多くの場合、検索エンジンのクローラーに、オブジェクトの詳細ページでもフラットページでもないビューのインデックスを作成する必要があります。 解決策は、これらのビューのURL名をitemsに明示的にリストし、サイトマップの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行は次のようになります。

from django.contrib.sitemaps import views

urlpatterns = [
    path('sitemap.xml', views.index, {'sitemaps': sitemaps}),
    path('sitemap-<section>.xml', views.sitemap, {'sitemaps': sitemaps},
         name='django.contrib.sitemaps.views.sitemap'),
]

これにより、sitemap-flatpages.xmlsitemap-blog.xmlの両方を参照するsitemap.xmlファイルが自動的に生成されます。 Sitemap クラスとsitemaps dictはまったく変更されません。

サイトマップの1つに50,000を超えるURLがある場合は、インデックスファイルを作成する必要があります。 この場合、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'),
]

テンプレートのカスタマイズ

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

from django.contrib.sitemaps import views

urlpatterns = [
    path('custom-sitemap.xml', views.index, {
        'sitemaps': sitemaps,
        'template_name': 'custom_sitemap.html'
    }),
    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は、各サイトマップへの絶対URLのリストです。


サイトマップ

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

  • alternates
  • changefreq
  • item
  • lastmod
  • location
  • priority

alternates属性は、 i18n および代替が有効になっている場合に使用できます。 これは、各URLのオプションの x_default フォールバックを含む、他の言語バージョンのリストです。 各代替は、locationおよびlang_codeキーを持つ辞書です。

バージョン3.2で変更: alternates属性が追加されました。


item属性が各URLに追加され、 Googleニュースサイトマップなどのテンプレートをより柔軟にカスタマイズできるようになりました。 サイトマップの items()publication_datatagsフィールドを持つアイテムのリストを返すと仮定すると、次のようなものが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>

Googleにpingを送信

サイトマップが変更されたときにGoogleに「ping」して、サイトのインデックスを再作成するように通知することをお勧めします。 サイトマップフレームワークは、まさにそれを行うための関数を提供します: django.contrib.sitemaps.ping_google()

ping_google(sitemap_url=None, ping_url=PING_URL, sitemap_uses_https=True)

ping_googleは、次のオプションの引数を取ります。

  • sitemap_url-サイトのサイトマップへの絶対パス(例:'/sitemap.xml')。 この引数が指定されていない場合、ping_googleは、URLconfで逆引き参照を実行して、サイトマップを把握しようとします。

  • ping_url-デフォルトはGoogleのPingツール: https://www.google.com/webmasters/tools/ping。

  • sitemap_uses_https-サイトでhttpsではなくhttpを使用している場合は、Falseに設定します。

ping_google()は、サイトマップURLを特定できない場合、例外django.contrib.sitemaps.SitemapNotFoundを発生させます。

最初にGoogleに登録してください!

ping_google()コマンドは、サイトを Google Search Console に登録している場合にのみ機能します。


ping_google()を呼び出す便利な方法の1つは、モデルのsave()メソッドからです。

from django.contrib.sitemaps import ping_google

class Entry(models.Model):
    # ...
    def save(self, force_insert=False, force_update=False):
        super().save(force_insert, force_update)
        try:
            ping_google()
        except Exception:
            # Bare 'except' because we could get a variety
            # of HTTP-related exceptions.
            pass

ただし、より効率的な解決策は、cronスクリプトまたはその他のスケジュールされたタスクから ping_google()を呼び出すことです。 この関数はGoogleのサーバーにHTTPリクエストを送信するため、save()を呼び出すたびにそのネットワークオーバーヘッドを導入したくない場合があります。

manage.pyを介してGoogleにpingを実行します

サイトマップアプリケーションがプロジェクトに追加されたら、ping_google管理コマンドを使用してGoogleにpingを実行することもできます。

python manage.py ping_google [/sitemap.xml]

サイトマップでhttpsではなくhttpを使用している場合は、このオプションを使用してください。