Spec-Zone.ru › Django 4.2

Фреймворк карты сайта

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

Обзор

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

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

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

Установка

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

  1. Добавьте 'django.contrib.sitemaps' в свой параметр INSTALLED_APPS.
  2. Убедитесь, что ваш параметр TEMPLATES содержит бэкенд DjangoTemplates, в котором параметр APP_DIRS установлен на значение True. Он по умолчанию включён, поэтому вам нужно изменить это только в случае изменения этого параметра.
  3. Убедитесь, что вы установили sites framework.

(Примечание: приложение карты сайта не устанавливает таблицы базы данных. Единственная причина, по которой оно должно находиться в INSTALLED_APPS, заключается в том, что загрузчик шаблонов Loader() может найти стандартные шаблоны.)

Инициализация

views.sitemap(request, sitemaps, section=None, template_name='sitemap.xml', content_type='application/xml')

Чтобы активировать генерацию карты сайта на вашем сайте Django, добавьте эту строку в ваш URLconf:

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/.

Функция представления карты сайта принимает дополнительный обязательный аргумент: {'sitemaps': sitemaps}. sitemaps должен быть словарем, в котором короткие метки разделов (например, blog или news) сопоставлены с их классом Sitemap (например, BlogSitemap или NewsSitemap). Он также может сопоставляться с экземпляром класса Sitemap (например, BlogSitemap(some_var)).

Sitemap классы

Класс Sitemap — это класс Python, представляющий «раздел» записей в вашей карте сайта. Например, один класс Sitemap может представлять все записи вашего блога, а другой — все события в вашем календаре событий.

В самом простом случае все эти разделы объединяются в одну карту сайта, но фреймворк также позволяет генерировать индекс карты сайта, который ссылается на отдельные файлы карт сайта, по одному на раздел. (См. Создание индекса карты сайта ниже.)

Классы 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-адресов в карте сайта. Если он не установлен, используется протокол, с помощью которого был запрошен карта сайта. Если карта сайта создается вне контекста запроса, значение по умолчанию — 'http'.

Устарело начиная с версии 4.0: Протокол по умолчанию для карт сайта, созданных вне контекста запроса, изменится с 'http' на 'https' в Django 5.0.

limit

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

Этот атрибут определяет максимальное количество URL-адресов, включенных на каждой странице карты сайта. Его значение не должно превышать значение по умолчанию 50000, которое является максимальным значением, разрешенным в протоколе карт сайта.

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()
Новое в Django 4.1.

Необязательно. Метод, возвращающий последнее значение, возвращенное lastmod. Эта функция используется для добавления атрибута lastmod к переменным контекста индекса Sitemap.

По умолчанию get_latest_lastmod() возвращает:

  • Если lastmod является атрибутом: lastmod.
  • Если lastmod является методом: Последнее значение lastmod возвращаемое вызовом метода со всеми элементами, возвращенными Sitemap.items().
get_languages_for_item(item, lang_code)
Новое в Django 4.2.

Необязательно. Метод, возвращающий последовательность кодов языка, для которых отображается элемент. По умолчанию get_languages_for_item() возвращает languages.

Сокращения

Фреймворк sitemap предоставляет удобный класс для распространенного случая:

class GenericSitemap(info_dict, priority=None, changefreq=None, protocol=None)

Класс django.contrib.sitemaps.GenericSitemap позволяет создавать sitemap, передавая ему словарь, который должен содержать как минимум запись queryset. Этот набор запросов будет использован для генерации элементов sitemap. Он также может содержать запись date_field, которая указывает поле даты для объектов, извлеченных из queryset. Это будет использоваться для атрибута lastmod и методов get_latest_lastmod() в сгенерированном sitemap.

Ключевые аргументы 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",
    ),
]

Sitemap для статических представлений

Часто требуется, чтобы роботы поисковых систем индексировали представления, которые не являются страницами подробностей объектов или плоскими страницами. Решением является явное указание имен URL для этих представлений в items и вызов reverse() в методе location sitemap. Например:

# 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",
    ),
]

Создание индекса sitemap

views.index(request, sitemaps, template_name='sitemap_index.xml', content_type='application/xml', sitemap_url_name='django.contrib.sitemaps.views.sitemap')

Фреймворк sitemap также позволяет создавать индекс sitemap, который ссылается на отдельные файлы 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},
        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 не изменятся.

Если все sitemaps возвращают lastmod методом Sitemap.get_latest_lastmod(), индекс sitemap будет иметь заголовок Last-Modified, равный последней дате lastmod.

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

Если вы не используете стандартное представление sitemap (например, если оно обернуто декоратором кеширования), вы должны назвать своё представление 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",
    ),
]
Изменено в Django 4.1:

Добавлен заголовок Last-Modified.

Настройка шаблонов

Если вы хотите использовать другой шаблон для каждого sitemap или индекса sitemap на вашем сайте, вы можете указать его, передав параметр 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 для каждого sitemap. Каждый URL имеет следующие атрибуты:

  • location: Путь (URL и страница) sitemap.
  • lastmod: Заполняется методом get_latest_lastmod() для каждого sitemap.
Изменено в Django 4.1:

Контекст был изменен на список объектов с атрибутами location и необязательными атрибутами lastmod.

Sitemap

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

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

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

Атрибут item был добавлен для каждого URL, чтобы обеспечить более гибкую настройку шаблонов, таких как карты сайта Google news. Предполагая, что items() возвращает список элементов с 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, когда ваш 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.xml').

    Если этот аргумент не указан, ping_google выполнит обратный поиск в вашей URLconf для URL с именами 'django.contrib.sitemaps.views.index' и затем 'django.contrib.sitemaps.views.sitemap' (без дополнительных аргументов), чтобы автоматически определить URL карты сайта.

  • ping_url - По умолчанию инструмент Ping 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 Search Console.

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

Spec-Zone.ru

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