今回のテーマは「サイトマップを自動作成する」です。SEO対策として検索エンジンにウェブサイトの更新を通知するためサイトマップを用意したいケースも多いと思います。今回はDjangoを用いてサイトマップを動的に生成する方法を見ていきます。
今回の内容は公式ドキュメントではThe sitemap frameworkの部分に相当します。
※本ページはページネーションを使うまで読まれた方を対象としています。そのためサンプルソースコードが省略されている場合があります。
準備
まずsettings.pyを変更する必要があります。
mysite/settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
+ 'django.contrib.sites',
+ 'django.contrib.sitemaps',
'debug_toolbar',
'base',
'thread',
'api',
'search',
]
+ SITE_ID = 1
次にデータベースのマイグレーションをします。
(venv)$ ./manage.py migrate
管理画面にアクセスしてドメイン名と表示名を変更します。今回はmydomain.comに修正しました。このサイトオブジェクトのIDが先程settings.pyで設定したSITE_IDと一致している必要があります。
Sitemap継承クラスを作る
ではサイトマップを作っていきましょう。DjangoにおいてサイトマップはSitemapクラスを継承したクラスにて作成します。thread/sitemaps.pyを作成します。尚、sitemaps.pyはDjangoで決まっているファイルではありませんので別の名前でもいいですし、他のファイルに書いても構いません。
thread/sitemaps.py
from django.contrib.sitemaps import Sitemap
from django.shortcuts import resolve_url
from . models import Topic, Category
class TopicSitemap(Sitemap):
priority = 0.5
changefreq = 'always'
def items(self):
return Topic.objects.all()
def location(self, obj):
return resolve_url('thread:topic', pk=obj.id)
class CategorySitemap(Sitemap):
priority = 0.5
changefreq = 'never'
def items(self):
return Category.objects.all()
def location(self, obj):
return resolve_url('thread:category', url_code=obj.url_code)
Sitemapクラスを継承したクラスを作成しています。このクラスではサイトマップを作成に必要な情報をクラスの属性として与えます。この際、静的な情報はクラス変数、動的な情報は関数を使って指定出来るようになっています。
指定できる属性は以下です。
items | [必須]ページのオブジェクト。イテレータブルなオブジェクトを指定する |
location | [オプション]itemsのURL |
lastmod | [オプション]ページ更新日時 |
changefreq | [オプション]ページの更新頻度 |
priority | [オプション]ページの重要度0〜1 |
limit | [オプション]ページネーションの区切り。デフォルトは50000 |
protocol | [オプション]httpプロトコル。デフォルトはhttp |
i18n | [オプション]URL表示に設定言語を適用するか True/False |
まず、items()メソッドでトピックのリストを与えています。この関数が返すイテレータブルなitemsの1つ1つに対してサイトマップが生成されます。ではこのitemsの要素であるitemのURLのを指定するためにlocation関数でURLを指定しましょう。トピックのURLは動的に変更するのでlocationは関数で与えます。このようにitemsで指定したリストの1要素を仮引数とする関数を作ることで動的なサイトマップを生成できます。
カテゴリー用のサイトマップも同様です。CategorySitemapクラスを作成して要素を指定しています。カテゴリーの場合はurl_codeを指定することに注意して下さい。
では、次に静的なページである利用規約やプライバシーポリシーについて見ていきましょう。これらのページは動的要素がないために非常に簡単です。base/sitemaps.pyを生成しましょう。
base/sitemaps.py
from django.contrib.sitemaps import Sitemap
from django.shortcuts import resolve_url
class BaseSitemap(Sitemap):
def items(self):
items = [
'base:top',
'base:policy',
'base:terms',
]
return items
def location(self, obj):
return resolve_url(obj)
def changefreq(self, obj):
if obj == 'base:top':
return 'always'
return 'never'
def priority(self, obj):
if obj == 'base:top':
return 0.8
return 0.1
基本的な考え方はthread/sitemaps.pyと同じです。ただitemsで’base:policy’のようにページのショートカット名でリストを生成することで効率的にサイトマップを生成することができます。上記でクラス変数として指定した属性についても関数で指定しています。両者を比べると理解がより進むのではないでしょうか。
URLの設定
では、作成したサイトマップを表示してみましょう。ここから先はmysite/urls.pyを変更していきます。
mysite/urls.py
from django.contrib import admin, auth
from django.urls import path, include
from django.conf import settings
from django.contrib.sitemaps.views import sitemap
+ from thread.sitemaps import TopicSitemap, CategorySitemap
+ from base.sitemaps import BaseSitemap
+ sitemaps = {
+ 'topic': TopicSitemap,
+ 'cateogry': CategorySitemap,
+ 'base': BaseSitemap,
+ }
urlpatterns = [
path('admin/', admin.site.urls),
path('accounts/', include('django.contrib.auth.urls')),
path('', include('base.urls')),
path('thread/', include('thread.urls')),
path('api/', include('api.urls')),
path('search/', include('search.urls')),
+ path('sitemap.xml', sitemap, {'sitemaps': sitemaps}),
]
if settings.DEBUG:
import debug_toolbar
urlpatterns = [
path('__debug__/', include(debug_toolbar.urls)),
] + urlpatterns
このように各アプリケーションでSitemap継承クラスを作成し、urls.pyでまとめるというのはDjangoのルールではないですが、分かりやすいので筆者は気に入っています。
では確認してみましょう。localhost:8080/sitemap.xmlにアクセスします。
最後に
Djangoのサイトマップ生成機能を使うと簡単に動的なサイトマップを作成することができますね。今回は基礎的な部分に着目したので、テンプレートをカスタマイズしたいという場合には公式ドキュメントを呼んでみて下さい。
Sponsored Link