Spec-Zone.ru › Django 6.0

Фреймворк sitemap

Django поставляется с высокоуровневым фреймворком для создания XML-файлов карты сайта.

Обзор

Карта сайта — это XML-файл на вашем сайте, который сообщает поисковым роботам, как часто меняются страницы и насколько «важны» одни страницы по отношению к другим страницам сайта. Эта информация помогает поисковым системам индексировать ваш сайт.

Фреймворк sitemap Django автоматизирует создание этого XML-файла, позволяя описать эту информацию в коде Python.

Он работает так же, как фреймворк распространения контента Django. Чтобы создать карту сайта, напишите класс Sitemap и укажите его в конфигурации URL.

Установка

Чтобы установить приложение sitemap, выполните следующие действия:

  1. Добавьте 'django.contrib.sitemaps' в настройку INSTALLED_APPS.
  2. Убедитесь, что настройка TEMPLATES содержит бэкенд DjangoTemplates, у которого параметр APP_DIRS установлен в True. По умолчанию он уже включён, поэтому менять настройку потребуется, только если вы ранее изменили её.
  3. Убедитесь, что вы установили 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:

  • alternates
  • changefreq
  • item
  • lastmod
  • location
  • priority

Атрибут 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/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API