Spec-Zone.ru › Django 3.2

Фреймворк для создания sitemap

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

Обзор

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

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

Он работает аналогично фреймворку Django для рассылки. Для создания sitemap напишите класс Sitemap и укажите его в вашем URLconf.

Установка

Для установки приложения 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')

Чтобы активировать генерацию 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, которое является максимальным значением, разрешенным в протоколе карт сайта.

i18n

Необязательно.

Логический атрибут, определяющий, будут ли URL-адреса в этой карте сайта генерироваться с использованием всех ваших LANGUAGES. Значение по умолчанию False.

languages
Новое в Django 3.2.

Необязательно.

Последовательность кодов языка для генерации альтернативных ссылок, когда i18n включён. Значение по умолчанию LANGUAGES.

alternates
Новое в Django 3.2.

Необязательно.

Логический атрибут. При использовании совместно с i18n сгенерированные URL-адреса будут содержать список альтернативных ссылок на версии других языков, используя атрибут hreflang. Значение по умолчанию False.

x_default
Новое в Django 3.2.

Необязательно.

Логический атрибут. Когда True альтернативные ссылки, генерируемые alternates, будут содержать hreflang="x-default" элемент обратной совместимости со значением LANGUAGE_CODE. Значение по умолчанию 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 не изменятся.

Вы должны создать файл индекса, если у одной из ваших карт сайта более 50 000 URL-адресов. В этом случае Django автоматически разделит карту сайта на страницы, и индекс отразит это.

Если вы не используете стандартное представление карты сайта — например, если оно обернуто декоратором кэширования — вы должны назвать своё представление для карты сайта и передать 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'
    }),
    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-адресов каждой из карт сайта.

Карта сайта

Переменная urlset представляет собой список URL-адресов, которые должны отображаться в карте сайта. Каждый URL-адрес предоставляет атрибуты, как определено в классе Sitemap:

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

Атрибут alternates доступен, когда i18n и alternates включены. Это список других языковых версий, включая необязательный резервный x_default, для каждого URL-адреса. Каждый альтернативный вариант — это словарь с ключами location и lang_code.

Изменено в Django 3.2:

Добавлен атрибут alternates.

Атрибут item добавлен для каждого URL-адреса, чтобы обеспечить более гибкую настройку шаблонов, например, карты сайта для новостей Google. Предполагая, что items() класса Sitemap вернёт список элементов с publication_data и полем tags, что-то вроде этого сгенерирует карту сайта, совместимую с Google News:

<?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, когда изменяется ваша карта сайта, чтобы сообщить ему о переиндексации вашего сайта. Фреймворк карт сайта предоставляет функцию для этого: django.contrib.sitemaps.ping_google().

ping_google(sitemap_url=None, ping_url=PING_URL, sitemap_uses_https=True)

ping_google принимает следующие необязательные аргументы:

  • sitemap_url — абсолютный путь к карте сайта вашего сайта (например, '/sitemap.xml'). Если этот аргумент не предоставлен, ping_google попытается определить вашу карту сайта, выполнив обратный поиск в вашем URLconf.
  • ping_url — по умолчанию используется инструмент уведомления Google: https://www.google.com/webmasters/tools/ping.
  • sitemap_uses_https — устанавливается в False, если ваш сайт использует http вместо https.

ping_google() вызывает исключение django.contrib.sitemaps.SitemapNotFound, если не удаётся определить URL-адрес вашей карты сайта.

Сначала зарегистрируйтесь в Google!

Команда ping_google() работает только в том случае, если вы зарегистрировали свой сайт в Инструментах для веб-мастеров Google.

Один из полезных способов вызова 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

Используйте этот параметр, если ваша карта сайта использует http вместо https.

© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/3.2/ref/contrib/sitemaps/

Spec-Zone.ru

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