revision-up-to: | 11321 (1.1) |
---|
Django には、 サイトマップ XML ファイルを簡単に生成できる高水準 のサイトマップ生成フレームワークが付属しています。
サイトマップ (sitemap) とは、自分のサイト上のページの更新頻度や特定のペー ジ間の「重要度」を検索エンジンのインデクサに対して知らせるために、Web サイ ト上に配置する XML ファイルです。この情報があると、検索エンジンがサイトのイ ンデクスを生成するときに役立ちます。
Django のサイトマップフレームワークを使うと、この XML ファイルの情報を Python コードで表現でき、ファイルの生成を自動化できます。
sitemaps は Django の 配信フレームワーク
によく似ています。サイトマップの生成は簡単で、ただ
Sitemap
クラスを書いて、
URLconf に指定するだけです。
sitemaps アプリケーションは以下の手順でインストールします:
INSTALLED_APPS
設定に'django.contrib.sitemaps'
を加 えます。TEMPLATE_LOADERS
設定に、'django.template.loaders.app_directories.load_template_source'
が入っているか確かめます。デフォルトの設定ファイルには入っているので、 注意が必要なのは設定を変更している時だけです。sites フレームワーク
をインストールし ておいてください。
(注意: sitemaps アプリケーションは、データベースに何らテーブルをインストール
しません。 INSTALLED_APPS
に sitemaps
を入れておかねばならな
いのは、
load_template_source()
テン
プレートローダがデフォルトのテンプレートを捜し出せるようにするためです。)
自分の Django サイト上でサイトマップ生成を行わせるには、 URLconf に以下の行を追加します:
(r'^sitemap.xml$', 'django.contrib.sitemaps.views.sitemap', {'sitemaps': sitemaps})
これで、 Django はクライアントが /sitemap.xml
にアクセスしたときに
サイトマップを生成するようになります。
サイトマップファイルの名前はさして重要ではありませんが、ファイルの場所は重
要です。検索エンジンは、サイトマップ内のリンクをインデクス化する際、ファイ
ルの置かれている URL レベルとその下のリンクしかたどりません。例えば、
sitemap.xml
がルートディレクトリ下にあれば、 Google はサイト上の全
ての URL を参照します。一方、サイトマップの場所が
/content/sitemap.xml
であれば、 /content/
で始まる URL しか
参照しません。
ビュー関数 sitemap()
には、必須の引数 {'sitemaps': sitemaps}
があり
ます。 sitemaps
はセクションラベル (例えば blog
や news
) を、
Sitemap
クラス (例えば BlogSitemap
や
NewsSitemap
) に対応づける辞書にします。あるいは、
Sitemap
クラスの インスタンス (例えば
BlogSitemap(some_bar)
) でもかまいません。
Sitemap
クラスとは、サイトマップ上のエン
トリの「セクション」を表現するための Python のクラスです。例えば、ある
Sitemap
クラスはブログ上の全てのエントリ
を表し、別のクラスはイベントカレンダー上の全てのイベントを表現する、といっ
た具合です。
最も単純化すれば、全てのセクションは sitemap.xml
という一つのファイ
ルにまとめあげられることになります。とはいえ、 sitemaps フレームワークを使
えば、各セクションごとに個別のサイトマップファイルがあるようなサイトマップ
インデクスを生成できます (後述の サイトマップインデクスを生成する を参照
してください)。
Sitemap
クラスは
django.contrib.sitemaps.Sitemap
のサブクラスでなければなりません。クラ
スはコードベースのどこに置いてもかまいません。
ブログシステムを使っていて、 Entry
というモデルがあるとしましょう。
サイトマップに全てのブログエントリへのリンクを含めたければ、サイトマップク
ラスは以下のようになります:
from django.contrib.sitemaps import Sitemap
from mysite.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()
はオブジェクトのリストを返すだけのメソッドで す。このメソッドの返すオブジェクトは、サイトマップの各プロパティ (location
,lastmod
,changefreq
,priority
) に対応するメ ソッドに渡されます。lastmod
は Python のdatetime
オブジェクトを返さ ねばなりません。- この例には
location
メソッドがありませんが、自分でメ ソッドを定義して、オブジェクトの URL を指定してもかまいません。デフォ ルトでは、location()
は各オブジェクトに対してget_absolute_url()
を呼び出し、その結果を返します。
Sitemap
¶Sitemap
のサブクラスでは、以下のメソッドや属性を定義できます:
items
¶必須です。 オブジェクトのリストを返すメソッドです。フレームワー
クはオブジェクトの 型 が何であるかを問いません。重要なのは、オブ
ジェクトが location()
, lastmod()
,
changefreq()
, priority()
といった
メソッドに渡されるという点だけです。
location
¶省略可能です。 メソッドまたは属性です。
メソッドとして定義する場合、 items()
の返すオブジェ
クトを引数にとり、オブジェクトに対する絶対 URLの文字列を計算して返
さねばなりません。
属性として定義する場合、 items()
の返す
全てのオブジェクトに共通して 使われる絶対 URL を表す文字列にしま
す。
いずれの場合も、「絶対 URL」とは、以下の例のようにプロトコルおよび ドメイン部を含まない URLを指します:
- 正しい:
'/foo/bar/'
- 誤り:
'example.com/foo/bar/'
- 誤り:
'http://example.com/foo/bar/'
location
を指定していない場合、フレームワークは
items()
の返す各オブジェクトに対して
get_absolute_url()
メソッドを呼び出します。
lastmod
¶省略可能です。 メソッドまたは属性です。
メソッドとして定義する場合、 items()
の返すオブジェ
クトを引数にとり、オブジェクトの最終更新日時を Python の
datetime.datetime
オブジェクトで返さねばなりません。
属性として定義する場合、 items()
の返す
全てのオブジェクトに共通して 使われるオブジェクトの最終更新日時を
Python の datetime.datetime
オブジェクトで返さねばなりません。
changefreq
¶省略可能です。 メソッドまたは属性です。
メソッドとして定義する場合、 items()
の返すオブジェ
クトを引数にとり、オブジェクトの更新頻度を Python の文字列型で返さ
ねばなりません。
属性として定義する場合、 items()
の返す
全てのオブジェクトに共通して 使われるオブジェクトの更新頻度を
Python の文字列型で返さねばなりません。
メソッド、属性を問わず、 changefreq
の値は以下のい
ずれかにします:
'always'
'hourly'
'daily'
'weekly'
'monthly'
'yearly'
'never'
priority
()¶省略可能です。 メソッドまたは属性です。
メソッドとして定義する場合、 items()
の返すオブジェ
クトを引数にとり、オブジェクトの重要度 (priority) を Python の文字
列型か浮動小数型で返さねばなりません。
属性として定義する場合、 items()
の返す
全てのオブジェクトに共通して 使われるオブジェクトの重要度を
Python の文字列型か浮動小数型で返さねばなりません。
priority
の値は 0.4
や 1.0
のようにします。
デフォルトの重要度は 0.5
です。重要度の詳細は
sitemaps.org のドキュメント を参照してください。
sitemaps フレームワークでは、よく使われる状況向けに、二つの便宜クラスを用意 しています:
FlatPageSitemap
¶django.contrib.sitemaps.FlatPageSitemap
クラスは、現在の
SITE_ID
(sites のドキュメント
参照) 向けの全ての フラットページ
を
検索し、サイトマップのエントリを生成します。各エントリには
location
属性だけが設定され、
lastmod
, changefreq
,
priority
は設定されません。
GenericSitemap
¶django.contrib.sitemaps.GenericSitemap
クラスは任意の
汎用ビュー <ref-generic-views> と組み合わせて使えます。
GenericSitemap
を使うには、汎用ビュー
に渡すのと同じ info_dict
を
GenericSitemap
に渡してインスタンスを
生成します。 info_dict
には少なくとも queryset
がなけれ
ばなりません。また、 info_dict
に queryset
で取り出され
るオブジェクトの日時のフィールドを指定する date_field
エントリ
がある場合、サイトマップ生成時にエントリの lastmod
属
性に使われます。 GenericSitemap
のコ
ンストラクタには、 priority
や
changefreq
といったキーワード引数も指定できます。
これらの引数の値は、全ての URL に共通の属性になります。
FlatpageSitemap
と
GenericSitemap
の両方を組み込んだ
URLconf の例は以下のようになります:
from django.conf.urls.defaults import *
from django.contrib.sitemaps import FlatPageSitemap, GenericSitemap
from mysite.blog.models import Entry
info_dict = {
'queryset': Entry.objects.all(),
'date_field': 'pub_date',
}
sitemaps = {
'flatpages': FlatPageSitemap,
'blog': GenericSitemap(info_dict, priority=0.6),
}
urlpatterns = patterns('',
# info_dict を使った汎用ビューの設定
# ...
# サイトマップ
(r'^sitemap.xml$', 'django.contrib.sitemaps.views.sitemap',
{'sitemaps': sitemaps})
)
sitemap フレームワークには、個々のサイトマップファイルを参照するサイトマッ
プインデクスを生成する機能もあります。サイトマップインデクスからサイトマッ
プファイルへの参照は、 sitemaps
辞書に定義されている各セクションご
とにひとつづつ作成されます。サイトマップインデクスを使うには、少しだけやり
方を変えます:
- URLconf に、
django.contrib.sitemaps.views.index()
とdjango.contrib.sitemaps.views.sitemap()
という二つのビューを使 います。django.contrib.sitemaps.views.sitemap()
にキーワード引数section
を指定します。
上の例にならうと、URLconf は以下のようになります:
(r'^sitemap.xml$', 'django.contrib.sitemaps.views.index', {'sitemaps': sitemaps}),
(r'^sitemap-(?P<section>.+)\.xml$', 'django.contrib.sitemaps.views.sitemap', {'sitemaps': sitemaps}),
この設定では、 sitemap-flatpages.xml
と sitemap-blog.xml
へ
の参照が入った sitemap.xml
が自動生成されます。
Sitemap
クラスと sitemaps
辞書に
手を加える必要はありません。
50,000 以上の URL を含むサイトマップの場合、インデクスファイルを生成せねば なりませんが、 Django は自動的にサイトマップをページ分割し、インデクスにそ の内容を反映します。
サイトマップの変更時に、Google に「ping を打」って、サイトのインデクスを再
構築させたい場合もあるでしょう。 sitemap フレームワークで ping を打つには、
django.contrib.sitemaps.ping_google()`()
を呼び出します。
ping_google
()¶ping_google()
にはオプションの引数 sitemap_url
がありま
す。この引数にはサイトのサイトマップの絶対 URL (例えば
'/sitemap.xml'
)を指定します。 sitemap_url
を指定しなかっ
た場合、 ping_google()
は URLconf の逆引きを行って、サイトマップ
の在処を探します。
サイトマップの URL を捜し出せなかった場合、 ping_google()
は django.contrib.sitemaps.SitemapNotFound
例外を送出します。
Google に登録しておきましょう!
ping_google()
が動作するのはは、 Google Webmaster Tools でサイ
トを登録してある場合だけです。
ping_google()
の用法として有用なのは、モデルの save()
メソッド
で呼び出すというものです:
from django.contrib.sitemaps import ping_google
class Entry(models.Model):
# ...
def save(self, force_insert=False, force_update=False):
super(Entry, self).save(force_insert, force_update)
try:
ping_google()
except Exception:
# Bare 'except' because we could get a variety
# of HTTP-related exceptions.
pass
とはいえ、 ping_google()
は Google のサーバに HTTP リクエストを送信
するので、 save()
のたびにネットワークアクセスのオーバヘッドが生じます。
もっと効率的にやりたければ、 cron 化されたスクリプトなど、一定の時点で実行
するようスケジュールしたタスクの中で ping_google()
を呼び出すとよい
でしょう。
manage.py
で Google に Ping を送信する¶サイトマップアプリケーションをプロジェクトに追加したら、 manage.py
コマ
ンドラインインタフェースを使って、以下のように Google サーバに ping を送信
できます:
python manage.py ping_google [/sitemap.xml]
Oct 26, 2017