Фреймворк sitemap
Django поставляется с высокоуровневым фреймворком для создания XML-файлов карты сайта.
Обзор
Карта сайта — это XML-файл на вашем сайте, который сообщает поисковым роботам, как часто меняются страницы и насколько «важны» одни страницы по отношению к другим страницам сайта. Эта информация помогает поисковым системам индексировать ваш сайт.
Фреймворк sitemap Django автоматизирует создание этого XML-файла, позволяя описать эту информацию в коде Python.
Он работает так же, как фреймворк распространения контента Django. Чтобы создать карту сайта, напишите класс Sitemap и укажите его в конфигурации URL.
Установка
Чтобы установить приложение 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')
Чтобы включить создание карт сайта на вашем сайте Django, добавьте эту строку в конфигурацию URL:
from django.contrib.sitemaps.views import sitemap
path(
"sitemap.xml",
sitemap,
{"sitemaps": sitemaps},
name="django.contrib.sitemaps.views.sitemap",
)
Это указывает Django создавать карту сайта, когда клиент обращается к /sitemap.xml.
Имя файла карты сайта не имеет значения, но важно его расположение. Поисковые системы индексируют в карте сайта только ссылки, относящиеся к текущему уровню URL и расположенным ниже уровням. Например, если sitemap.xml находится в корневом каталоге, он может содержать ссылки на любые URL вашего сайта. Однако если карта сайта находится по адресу /content/sitemap.xml, она может содержать ссылки только на URL, начинающиеся с /content/.
Представлению sitemap требуется дополнительный обязательный аргумент: {'sitemaps': sitemaps}. sitemaps должен быть словарём, который сопоставляет краткую метку раздела (например, blog или news) с классом Sitemap (например, BlogSitemap или NewsSitemap). Также он может сопоставлять метку с экземпляром класса Sitemap (например, BlogSitemap(some_var)).
Классы Sitemap
Класс Sitemap — это класс Python, представляющий «раздел» записей в вашей карте сайта. Например, один класс Sitemap может представлять все записи вашего блога, а другой — все события в календаре мероприятий.
В простейшем случае все эти разделы объединяются в один sitemap.xml, но также можно использовать фреймворк для создания индекса карты сайта со ссылками на отдельные файлы карт сайта — по одному на каждый раздел. (См. раздел Создание индекса карты сайта ниже.)
Классы Sitemap должны быть подклассами 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объектов. Возвращённые объекты передаются всем вызываемым методам, соответствующим свойствам карты сайта (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и не отправлял карту сайта, если она не изменилась.
-
paginator[исходный код] -
Необязательный.
Это свойство возвращает объект
Paginatorдляitems. Если вы создаёте карты сайта пакетами, можно переопределить это свойство как кэшируемое, чтобы избежать нескольких вызововitems().
-
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 в карте сайта. Если он не задан, используется протокол, по которому был запрошен файл карты сайта. Если карта сайта создаётся вне контекста запроса, по умолчанию используется'https'.
-
limit -
Необязательный.
Этот атрибут задаёт максимальное количество URL на каждой странице карты сайта. Его значение не должно превышать
50000— значение по умолчанию и верхний предел, разрешённый протоколом Sitemaps.
-
i18n -
Необязательный.
Булев атрибут, определяющий, нужно ли создавать URL этой карты сайта с использованием всех языков из
LANGUAGES. Значение по умолчанию —False.
-
languages -
Необязательный.
Последовательность кодов языков, используемых для создания альтернативных ссылок, если включён атрибут
i18n. По умолчанию используетсяLANGUAGES.
-
alternates -
Необязательный.
Булев атрибут. При использовании вместе с
i18nдля каждого созданного URL будет указан список альтернативных ссылок на версии на других языках с использованием атрибута hreflang. Значение по умолчанию —False.
-
x_default -
Необязательный.
Булев атрибут. Если
True, альтернативные ссылки, созданные с помощьюalternates, будут содержать резервную записьhreflang="x-default"со значениемLANGUAGE_CODE. Значение по умолчанию —False.
-
get_latest_lastmod()[исходный код] -
Необязательный. Метод, возвращающий самое позднее значение, возвращённое методом
lastmod. Эта функция используется для добавления атрибутаlastmodв переменные контекста индекса карты сайта.По умолчанию
get_latest_lastmod()возвращает:- Если
lastmod— атрибут:lastmod. - Если
lastmod— метод: самое позднее значениеlastmod, возвращённое при вызове метода для всех элементов, возвращённых методомSitemap.items().
- Если
-
get_languages_for_item(item)[исходный код] -
Необязательный. Метод, возвращающий последовательность кодов языков, на которых отображается элемент. По умолчанию
get_languages_for_item()возвращаетlanguages.
-
Упрощённые средства
Для распространённого случая во фреймворке sitemap предусмотрен вспомогательный класс:
-
class GenericSitemap(info_dict, priority=None, changefreq=None, protocol=None)[исходный код] -
Класс
django.contrib.sitemaps.GenericSitemapпозволяет создать карту сайта, передав ему словарь, который должен содержать как минимум записьqueryset. Этот набор запросов будет использоваться для создания элементов карты сайта. Также в словаре может быть записьdate_field, указывающая поле даты для объектов, полученных изqueryset. Это поле будет использоваться атрибутомlastmodи методомget_latest_lastmod()в созданной карте сайта.Именованные аргументы
priority,changefreqиprotocolпозволяют задать эти атрибуты для всех URL.
Пример
Вот пример конфигурации URL с использованием 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')
Фреймворк sitemap также позволяет создавать индекс карты сайта со ссылками на отдельные файлы карт сайта — по одному для каждого раздела, определённого в вашем словаре sitemaps. Использование отличается только следующим:
- В конфигурации URL используются два представления:
django.contrib.sitemaps.views.index()иdjango.contrib.sitemaps.views.sitemap(). - Представлению
django.contrib.sitemaps.views.sitemap()нужно передать именованный аргументsection.
Строки конфигурации URL для приведённого выше примера будут выглядеть так:
from django.contrib.sitemaps import views
urlpatterns = [
path(
"sitemap.xml",
views.index,
{"sitemaps": sitemaps},
name="django.contrib.sitemaps.views.index",
),
path(
"sitemap-<section>.xml",
views.sitemap,
{"sitemaps": sitemaps},
name="django.contrib.sitemaps.views.sitemap",
),
]
Это автоматически создаст файл sitemap.xml со ссылками на sitemap-flatpages.xml и sitemap-blog.xml. Классы Sitemap и словарь sitemaps остаются без изменений.
Если все карты сайта возвращают lastmod методом Sitemap.get_latest_lastmod(), индекс карты сайта будет содержать заголовок Last-Modified, равный самой поздней дате lastmod.
Создайте файл индекса, если одна из ваших карт сайта содержит более 50 000 URL. В этом случае Django автоматически разбьёт карту сайта на страницы, и это будет отражено в индексе.
Если вы не используете стандартное представление sitemap — например, если оно обёрнуто декоратором кэширования, — необходимо задать имя представлению карты сайта и передать 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"},
name="django.contrib.sitemaps.views.index",
),
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 — это список объектов, содержащих атрибуты location и lastmod для каждой карты сайта. Для каждого URL доступны следующие атрибуты:
-
location: Расположение (URL и страница) карты сайта. -
lastmod: Заполняется методомget_latest_lastmod()для каждой карты сайта.
Карта сайта
Переменная urlset — это список URL, которые должны быть включены в карту сайта. Для каждого URL доступны атрибуты, определённые в классе Sitemap:
alternateschangefreqitemlastmodlocationpriority
Атрибут alternates доступен, если включены i18n и alternates. Это список версий на других языках, включая необязательный резервный вариант x_default, для каждого URL. Каждый альтернативный вариант представляет собой словарь с ключами location и lang_code.
Для каждого URL был добавлен атрибут item, позволяющий гибче настраивать шаблоны, например для карт сайта Google Новостей. Если предположить, что items карты сайта возвращает список объектов с полем publication_data и полем tags, следующий пример создаст карту сайта, совместимую с Google Новостями:
<?xml version="1.0" encoding="UTF-8"?>
<urlset
xmlns="https://www.sitemaps.org/schemas/sitemap/0.9"
xmlns:news="https://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>
© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/6.0/ref/contrib/sitemaps/