Spec-Zone.ru › Django 1.10

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

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

Обзор

Карта сайта — это 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

url(r'^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() — это просто метод, возвращающий список объектов. Объекты, возвращенные методом, будут переданы в любые вызываемые методы, соответствующие свойству карты сайта (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, что является максимальным значением, разрешенным в протоколе Sitemaps.

i18n

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

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

Сокращения

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

class GenericSitemap [source]

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

Пример

Вот пример URLconf, использующего GenericSitemap:

from django.conf.urls import url
from django.contrib.sitemaps import GenericSitemap
from django.contrib.sitemaps.views import sitemap
from blog.models import Entry

info_dict = {
    'queryset': Entry.objects.all(),
    'date_field': 'pub_date',
}

urlpatterns = [
    # some generic view using info_dict
    # ...

    # the sitemap
    url(r'^sitemap\.xml$', sitemap,
        {'sitemaps': {'blog': GenericSitemap(info_dict, priority=0.6)}},
        name='django.contrib.sitemaps.views.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.conf.urls import url
from django.contrib.sitemaps.views import sitemap

from .sitemaps import StaticViewSitemap
from . import views

sitemaps = {
    'static': StaticViewSitemap,
}

urlpatterns = [
    url(r'^$', views.main, name='main'),
    url(r'^about/$', views.about, name='about'),
    url(r'^license/$', views.license, name='license'),
    # ...
    url(r'^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 = [
    url(r'^sitemap\.xml$', views.index, {'sitemaps': sitemaps}),
    url(r'^sitemap-(?P<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 = [
    url(r'^sitemap\.xml$',
        cache_page(86400)(sitemaps_views.index),
        {'sitemaps': sitemaps, 'sitemap_url_name': 'sitemaps'}),
    url(r'^sitemap-(?P<section>.+)\.xml$',
        cache_page(86400)(sitemaps_views.sitemap),
        {'sitemaps': sitemaps}, name='sitemaps'),
]

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

Если вы хотите использовать другой шаблон для каждой карты сайта или индекса карты сайта, доступной на вашем сайте, вы можете указать его, передав параметр template_name в представления sitemap и index через URLconf:

from django.contrib.sitemaps import views

urlpatterns = [
    url(r'^custom-sitemap\.xml$', views.index, {
        'sitemaps': sitemaps,
        'template_name': 'custom_sitemap.html'
    }),
    url(r'^custom-sitemap-(?P<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="http://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.

Один из полезных способов вызова ping_google() — из метода save() модели:

from django.contrib.sitemaps import ping_google

class Entry(models.Model):
    # ...
    def save(self, force_insert=False, force_update=False):
        super(Entry, self).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/1.10/ref/contrib/sitemaps/

Spec-Zone.ru

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