Spec-Zone.ru › Django 4.0

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

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

Обзор

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

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

Он работает очень похоже на фреймворк синдикации Django. Для создания карты сайта напишите класс 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')

Чтобы активировать генерацию карт сайта на вашем сайте 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 — это класс 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() для каждого объекта и возвращает результат.

Ссылка на класс карты сайта

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
Новое в Django 3.2.

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

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

alternates
Новое в Django 3.2.

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

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

x_default
Новое в Django 3.2.

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

Логический атрибут. Если True, альтернативные ссылки, сгенерированные alternates, будут содержать запись fallback hreflang="x-default" со значением LANGUAGE_CODE. Значение по умолчанию False.

Сокращения

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

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'),
]

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

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

  • Вы используете две представления в вашем 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 не изменятся.

Вы должны создать файл индекса, если у одной из ваших карт сайта более 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'
    }, 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 представляет собой список абсолютных URL-адресов каждой из карт сайта.

Карта сайта

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

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

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

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

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

Атрибут item был добавлен для каждого URL, чтобы позволить более гибкую настройку шаблонов, таких как карты новостей Google. Предполагая, что 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, когда ваша карта сайта изменится, чтобы сообщить ей о необходимости повторной индексации вашего сайта. Фреймворк карт сайта предоставляет функцию для этого: 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 - По умолчанию инструмент Google Ping: 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.0/ref/contrib/sitemaps/

Spec-Zone.ru

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