Фреймворк для создания sitemap
Django поставляется с высокоуровневым фреймворком для генерации sitemap, позволяющим создавать XML-файлы sitemap.
Обзор
Sitemap — это XML-файл на вашем веб-сайте, который сообщает поисковым индексаторам, как часто изменяются ваши страницы и насколько «важны» определенные страницы по отношению к другим страницам на вашем сайте. Эта информация помогает поисковым системам индексировать ваш сайт.
Фреймворк Django для sitemap автоматизирует создание этого XML-файла, позволяя вам выразить эту информацию на языке Python.
Он работает аналогично фреймворку Django для рассылки. Для создания sitemap напишите класс Sitemap и укажите его в вашем URLconf.
Установка
Для установки приложения sitemap выполните следующие шаги:
- Добавьте
'django.contrib.sitemaps'в свой параметрINSTALLED_APPS. - Убедитесь, что ваш параметр
TEMPLATESсодержит бэкендDjangoTemplates, где параметрAPP_DIRSустановлен наTrue. По умолчанию он настроен, поэтому вам нужно изменить это только в случае изменения настроек. - Убедитесь, что вы установили
sites framework.
(Примечание: приложение sitemap не устанавливает таблицы базы данных. Единственная причина, по которой оно должно быть указано в INSTALLED_APPS, заключается в том, что загрузчик шаблонов Loader() может найти шаблоны по умолчанию.)
Инициализация
-
views.sitemap(request, sitemaps, section=None, template_name='sitemap.xml', content_type='application/xml')
Чтобы активировать генерацию sitemap на вашем сайте Django, добавьте эту строку в ваш URLconf:
from django.contrib.sitemaps.views import sitemap
path('sitemap.xml', sitemap, {'sitemaps': sitemaps},
name='django.contrib.sitemaps.views.sitemap')
Это сообщает Django о построении sitemap при обращении клиента к /sitemap.xml.
Имя файла sitemap не важно, но расположение — да. Поисковые системы будут индексировать только ссылки в вашем sitemap для текущего уровня URL и ниже. Например, если sitemap.xml находится в корневом каталоге, он может ссылаться на любые URL на вашем сайте. Однако, если ваш sitemap находится по адресу /content/sitemap.xml, он может ссылаться только на URL, начинающиеся с /content/.
Метод sitemap-представления принимает дополнительный обязательный аргумент: {'sitemaps': sitemaps}. sitemaps должен быть словарем, который сопоставляет короткое имя раздела (например, blog или news) с его классом Sitemap (например, BlogSitemap или NewsSitemap). Он также может сопоставляться с экземпляром класса Sitemap (например, BlogSitemap(some_var)).
Классы sitemap
Класс Sitemap — это класс Python, представляющий «раздел» записей в вашем sitemap. Например, один класс Sitemap может представлять все записи вашего блога, а другой — все события в вашем календаре событий.
В простейшем случае все эти разделы объединяются в один sitemap.xml, но также можно использовать фреймворк для генерации индекса sitemap, который ссылается на отдельные файлы sitemap, по одному на каждый раздел. (См. Создание индекса sitemap ниже.)
Классы Sitemap должны быть подклассами django.contrib.sitemaps.Sitemap. Они могут располагаться где угодно в вашем коде.
Пример
Предположим, у вас есть система блога с моделью Entry и вы хотите, чтобы ваш sitemap включал все ссылки на ваши отдельные записи блога. Вот как может выглядеть ваш класс sitemap:
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объектов. Объекты, возвращаемые методом, будут передаваться любым вызываемым методам, соответствующим свойству sitemap (location,lastmod,changefreqиpriority). -
lastmodдолжен возвращатьdatetime. - В этом примере нет метода
location, но вы можете его предоставить, чтобы указать URL для вашего объекта. По умолчаниюlocation()вызываетget_absolute_url()для каждого объекта и возвращает результат.
Справочник по классам sitemap
-
class Sitemap -
Класс
Sitemapможет определять следующие методы/атрибуты:-
items -
Обязательно. Метод, возвращающий последовательность или
QuerySetобъектов. Фреймворк не заботится о типе объектов; важно лишь, чтобы эти объекты были переданы методамlocation(),lastmod(),changefreq()иpriority().
-
location -
Необязательно. Может быть как методом, так и атрибутом.
Если это метод, он должен возвращать абсолютный путь для данного объекта, как возвращает
items().Если это атрибут, его значение должно быть строкой, представляющей абсолютный путь, используемый для каждого объекта, возвращаемого
items().В обоих случаях «абсолютный путь» означает URL, не включающий протокол или домен. Примеры:
- Хорошо:
'/foo/bar/' - Плохо:
'example.com/foo/bar/' - Плохо:
'https://example.com/foo/bar/'
Если
locationне задан, фреймворк вызовет методget_absolute_url()для каждого объекта, возвращаемогоitems().Чтобы указать протокол, отличный от
'http', используйтеprotocol. - Хорошо:
-
lastmod -
Необязательно. Может быть как методом, так и атрибутом.
Если это метод, он должен принимать один аргумент – объект, возвращаемый
items()– и возвращать дату/время последнего изменения объекта в форматеdatetime.Если это атрибут, его значение должно быть
datetime, представляющим дату/время последнего изменения для каждого объекта, возвращаемогоitems().Если у всех элементов в карте сайта есть
lastmod, карта сайта, сгенерированнаяviews.sitemap(), будет иметь заголовокLast-Modified, равный последнейlastmod. Вы можете активироватьConditionalGetMiddleware, чтобы Django должным образом реагировал на запросы с заголовкомIf-Modified-Since, что предотвратит отправку карты сайта, если она не изменилась.
-
changefreq -
Необязательно. Может быть как методом, так и атрибутом.
Если это метод, он должен принимать один аргумент – объект, возвращаемый
items()– и возвращать частоту обновления объекта в виде строки.Если это атрибут, его значение должно быть строкой, представляющей частоту обновления каждого объекта, возвращаемого
items().Возможные значения для
changefreq(как для метода, так и для атрибута):'always''hourly''daily''weekly''monthly''yearly''never'
-
priority -
Необязательно. Может быть как методом, так и атрибутом.
Если это метод, он должен принимать один аргумент – объект, возвращаемый
items()– и возвращать приоритет объекта в виде строки или числа с плавающей точкой.Если это атрибут, его значение должно быть строкой или числом с плавающей точкой, представляющим приоритет каждого объекта, возвращаемого
items().Примеры значений для
priority:0.4,1.0. По умолчанию приоритет страницы равен0.5. Смотрите документацию sitemaps.org для получения дополнительной информации.
-
protocol -
Необязательно.
Этот атрибут определяет протокол (
'http'или'https') URL-адресов в карте сайта. Если он не задан, используется протокол, с помощью которого была запрошена карта сайта. Если карта сайта создаётся вне контекста запроса, значение по умолчанию –'http'.
-
limit -
Необязательно.
Этот атрибут определяет максимальное количество URL-адресов, включённых на каждой странице карты сайта. Его значение не должно превышать значение по умолчанию
50000, которое является верхним пределом, разрешённым в протоколе Sitemaps.
-
i18n -
Необязательно.
Логический атрибут, определяющий, должны ли URL-адреса этой карты сайта генерироваться с использованием всех ваших
LANGUAGES. Значение по умолчанию –False.
-
Сокращения
Фреймворк карты сайта предоставляет удобный класс для распространённого случая:
-
class GenericSitemap(info_dict, priority=None, changefreq=None, protocol=None) -
Класс
django.contrib.sitemaps.GenericSitemapпозволяет создать карту сайта, передав ему словарь, который должен содержать как минимум записьqueryset. Этот набор данных будет использован для генерации элементов карты сайта. Он также может содержать записьdate_field, которая указывает поле даты для объектов, извлечённых изqueryset. Это будет использовано для атрибутаlastmodв сгенерированной карте сайта.Ключевые аргументы
priority,changefreqиprotocolпозволяют указать эти атрибуты для всех URL-адресов.
Пример
Вот пример файла URLconf, использующего GenericSitemap:
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 и вызвать reverse() в методе location карты сайта. Например:
# 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. Единственные различия в использовании:
- Вы используете два представления в вашем URLconf:
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}),
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 больше 50 000 URL-адресов. В этом случае Django автоматически разделит sitemap на страницы, и индекс будет отражать это.
Если вы не используете стандартное представление sitemap — например, если оно обернуто декоратором кэширования — вам необходимо указать имя вашего представления sitemap и передать sitemap_url_name в представление index:
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'),
]
Настройка шаблонов
Если вы хотите использовать другой шаблон для каждого sitemap или sitemap index, доступных на вашем сайте, вы можете указать его, передав параметр 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-адресов каждого sitemap.
Sitemap
Переменная urlset представляет собой список URL-адресов, которые должны отображаться в sitemap. Каждый URL-адрес предоставляет атрибуты, определенные в классе Sitemap:
changefreqitemlastmodlocationpriority
Атрибут item был добавлен для каждого URL-адреса, чтобы обеспечить более гибкую настройку шаблонов, например, для sitemap новостей Google. Предполагая, что items() класса Sitemap возвращает список элементов с publication_data и полем tags, что-то подобное сгенерирует совместимый с Google News sitemap:
<?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
Возможно, вам захочется отправить уведомление в Google, когда ваш sitemap изменится, чтобы сообщить ему о необходимости переиндексации вашего сайта. В рамках фреймворка sitemaps для этого существует функция: django.contrib.sitemaps.ping_google().
-
ping_google(sitemap_url=None, ping_url=PING_URL, sitemap_uses_https=True) -
ping_googleпринимает следующие необязательные аргументы:-
sitemap_url- Абсолютный путь к sitemap вашего сайта (например,'/sitemap.xml'). Если этот аргумент не указан,ping_googleпопытается определить ваш sitemap, выполнив обратный поиск в вашем URLconf. -
ping_url- По умолчанию используется инструмент Ping от Google: https://www.google.com/webmasters/tools/ping. -
sitemap_uses_https- Устанавливается вFalse, если ваш сайт используетhttp, а неhttps.
ping_google()вызывает исключениеdjango.contrib.sitemaps.SitemapNotFound, если не удается определить URL вашего sitemap.Добавлено в Django 2.2:Добавлен аргумент
sitemap_uses_https. В более ранних версиях Django всегда использовалсяhttpдля URL sitemap. -
Сначала зарегистрируйтесь в 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().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() из скрипта cron или другой задачи с расписанием. Функция выполняет HTTP-запрос к серверам Google, поэтому, возможно, вы не захотите добавлять эту сетевую нагрузку каждый раз, когда вызываете save().
Отправка уведомления в Google через manage.py
-
django-admin ping_google [sitemap_url]
После добавления приложения sitemaps в ваш проект вы также можете отправить уведомление в Google с помощью команды управления ping_google:
python manage.py ping_google [/sitemap.xml]
-
--sitemap-uses-http
Используйте этот параметр, если ваш sitemap использует http вместо https.
© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/3.0/ref/contrib/sitemaps/