Spec-Zone.ru › Django 2.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.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 [source]

Класс Sitemap может определять следующие методы/атрибуты:

items [source]

Обязательный. Метод, возвращающий последовательность или QuerySet объектов. Фреймворк не заботится о типе объектов; важно лишь, чтобы эти объекты передавались методам location(), lastmod(), changefreq() и priority().

location [source]

Необязательный. Может быть методом или атрибутом.

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

i18n

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

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

Быстрые способы создания

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

class GenericSitemap(info_dict, priority=None, changefreq=None, protocol=None) [source]

Класс django.contrib.sitemaps.GenericSitemap позволяет создавать сайтмапу, передавая ему словарь, который должен содержать как минимум запись queryset. Этот 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'),
]

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 также имеет возможность создания индекса 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}),
    path('sitemap-<section>.xml', views.sitemap, {'sitemaps': sitemaps},
         name='django.contrib.sitemaps.views.sitemap'),
]

Это автоматически сгенерирует файл sitemap.xml, который ссылается на sitemap-flatpages.xml и sitemap-blog.xml. Классы Sitemap и словарь sitemaps остаются неизменными.

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

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

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

Sitemap

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

  • changefreq
  • item
  • lastmod
  • location
  • priority

Атрибут item был добавлен для каждого URL, чтобы позволить более гибкую настройку шаблонов, таких как Sitemap для новостей Google. Предполагая, что items() класса Sitemap вернёт список элементов с publication_data и tags полями, что-то вроде этого сгенерирует Sitemap, совместимый с 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, чтобы сообщить ему о переиндексации вашего сайта. Фреймворк Sitemap предоставляет функцию для этого: django.contrib.sitemaps.ping_google().

ping_google(sitemap_url=None, ping_url=PING_URL, sitemap_uses_https=True) [source]

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

  • sitemap_url — абсолютный путь к Sitemap вашего сайта (например, '/sitemap.xml'). Если этот аргумент не предоставлен, ping_google попытается определить ваш Sitemap, выполнив обратный поиск в URLconf.
  • 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.

Добавлен в Django 2.2:

Аргумент sitemap_uses_https был добавлен. Более старые версии Django всегда использовали http для URL Sitemap.

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

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

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

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

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

Spec-Zone.ru

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