Spec-Zone.ru › Django 2.0

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

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() — это просто метод, возвращающий список объектов. Объекты, возвращаемые этим методом, будут переданы в любые вызываемые методы, соответствующие свойству карты сайта (location, lastmod, changefreq и priority).
  • lastmod должен возвращать datetime.
  • В этом примере нет метода location, но вы можете его предоставить, чтобы указать URL для вашего объекта. По умолчанию, location() вызывает get_absolute_url() для каждого объекта и возвращает результат.

Sitemap справочник по классам

class Sitemap [source]

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

items [source]

Обязательно. Метод, возвращающий список объектов. Фреймворк не заботится о типе объектов; важно, чтобы эти объекты передавались методам 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, которое является верхним пределом, разрешенным в протоколе карт сайта.

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

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

Был добавлен ключевой аргумент protocol.

Пример

Вот пример 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'),
]

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

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

  • changefreq
  • item
  • lastmod
  • location
  • priority

Атрибут 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() [source]

ping_google() принимает необязательный аргумент sitemap_url, который должен быть абсолютным путем к карте сайта вашего сайта (например, '/sitemap.xml'). Если этот аргумент не указан, ping_google() попытается определить вашу карту сайта, выполнив обратный поиск в вашем URLconf.

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

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

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

Spec-Zone.ru

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