Блог на Django #30: Добавление карты сайта

В Django есть фреймворк для карты сайта, который позволяет генерировать ее динамически. Карта сайта — это файл в формате XML, который сообщает поисковым системам о том, какие страницы имеются на сайте, их релевантность и частоту обновления. С ее помощью можно помочь поисковым роботом индексировать весь контент.

Этот фреймворк опирается на django.contrib.sites, который позволяет делать объектами отдельные сайты целого проекта. Это очень удобно, если нужно запустить несколько сайтов с помощью одного проекта Django. Для установки фреймворка нужно активировать приложения sites и sitemap в проекте. Отредактируйте файл settings.py проекта и добавьте в INSTALLED_APPS пункты django.contrib.sites и django.contrib.sitemaps. Также определите новую настройку с SITE_ID:

SITE_ID = 1 

# Application definition 
INSTALLED_APPS = [ 
    # ... 
    'django.contrib.sites', 
    'django.contrib.sitemaps', 
]

Теперь запустите эту команду для создания таблиц приложения сайта Django в базе данных:

python manage.py migrate

Вывод должен быть следующим:

Applying sites.0001_initial... OK
Applying sites.0002_alter_domain_unique... OK

Приложение sites теперь синхронизировано с базой данных. Создайте новый файл в папке приложения blog и назовите его sitemap.py. Откройте файл и добавьте следующий код:

from django.contrib.sitemaps import Sitemap  
from .models import Post  
  
  
class PostSitemap(Sitemap):  
    changefreq = 'weekly'  
    priority = 0.9  
  
    def items(self):  
        return Post.published.all()  
      
    def lastmod(self, obj):  
        return obj.updated

Создадим собственную карту сайта, наследуя класс Sitemap модуля sitemaps. Атрибуты changefreq и priotiy указывают на частоту изменения страниц с постами и их релевантность на сайте (максимальное значение — 1). Метод items() возвращает QuerySet объектов для включения в базу данных. По умолчанию Django вызывает метод get_absolute_url() для каждого объекта для получения URL. Вспомните о созданном методе для получения канонических URL для постов. Если необходимо определить URL для каждого объекта, можно добавить метод location к классу карты сайта. Метод lastmod получает каждый объект, который вернул метод items() и в свою очередь возвращает дату, когда тот последний раз изменился. И changefreq, и priority могут быть как методами, так и атрибутами. Полностью фреймворк карты сайта описан в документации Django https://docs.djangoproject.com/en/2.0/ref/contrib/sitemaps/.

Осталось лишь добавить URL карты сайта. Отредактируйте главный файл urls.py проекта и добавьте ссылку.

# mysite/urls.py
from django.urls import path, include  
from django.contrib import admin  
from django.contrib.sitemaps.views import sitemap  
from blog.sitemap import PostSitemap  
  
sitemaps = {  
    'posts': PostSitemap,  
}  
  
urlpatterns = [  
    path('admin/', admin.site.urls),  
    path('blog/', include('blog.urls', namespace='blog')),  
    path('sitemap.xml', sitemap, {'sitemaps': sitemaps},  
	 name='django.contrib.sitemaps.views.sitemap')  
]

В этом коде были включены необходимые импорты, а также определен словарь карт сайта. Также определен шаблон URL, который ведет на sitemap.xml и использует представление карты сайта. Запустите сервер разработки и введите в браузере https://127.0.0.1:8000/sitemap.xml. Должен появиться следующий XML-вывод:

<urlset>
  <url>
    <loc>https://example.com/blog/2020/2/2/markdown-post/</loc>
    <lastmod>2020-02-02</lastmod>
    <changefreq>weekly</changefreq>
    <priority>0.9</priority>
  </url>
  <url>
    <loc>
      https://example.com/blog/2019/12/14/ai-community-needs-take-responsibility-its-technology-and-its-actions/
    </loc>
    <lastmod>2019-12-28</lastmod>
    <changefreq>weekly</changefreq>
    <priority>0.9</priority>
  </url>
...
</urlset>

URL для каждого поста создается с помощью метода get_absolute_url().

Атрибут lastmod соответствует полю updated поста, как было определено в карте сайта. А атрибуты changefreq и priority берутся из класса PostSitemap. Домен, используемый для создания URL — example.com. Он исходит из объекта Site, который хранится в базе данных. Этот объект по умолчанию создается при синхронизации структуры сайта с базой данных. Откройте https://127.0.0.1:8000/admin/sites/site/ в браузере. Отобразится следующее:

Отображение списка структуры сайта

На этом скриншоте изображено представление для отображения списка структуры сайта. Здесь можно назначить домен или хост, чтобы они использовались структуры сайта и приложениями, которые с ним работают. Для генерации URL в локальной среде нужно изменить доменное имя на localhost:8000, как показано на предыдущем скриншоте и сохранить:

Настройка URL для sitemap в локальной среде

URL, отображаемые в ленте, теперь будут строиться с помощью имени хоста. При развертывании сайта нужно будет использовать доменное имя.