Spec-Zone.ru › Django 4.1

Каркас сайта

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

Сокращения

Фреймворк 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-адресов.

Пример

Вот пример 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 остаются неизменными.

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

Вы должны создать файл индекса, если у одной из ваших карт сайта более 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'),
]
Изменено в Django 4.1:

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

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

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

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

Карта сайта

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

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

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

Атрибут 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 вашего сайта (например, '/sitemap.xml').

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

  • ping_url - По умолчанию используется инструмент ping Google: https://www.google.com/webmasters/tools/ping.
  • sitemap_uses_https - Установите в False, если ваш сайт использует http вместо https.

ping_google() вызывает исключение django.contrib.sitemaps.SitemapNotFound, если не может определить URL вашего sitemap.

Сначала зарегистрируйтесь в 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

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

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

Spec-Zone.ru

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