Spec-Zone.ru › Django 1.8

Фреймворк для создания файлов sitemap

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

Обзор

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

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

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

Чтобы активировать генерацию sitemap на вашем сайте Django, добавьте эту строку в ваш URLconf:

from django.contrib.sitemaps.views import sitemap

url(r'^sitemap\.xml$', sitemap, {'sitemaps': sitemaps},
    name='django.contrib.sitemaps.views.sitemap')

Это сообщает Django о построении sitemap, когда клиент обращается к /sitemap.xml.

Имя файла sitemap не имеет значения, но важно его расположение. Поисковые системы будут индексировать только ссылки в вашем sitemap для текущего уровня URL и ниже. Например, если sitemap.xml находится в корневом каталоге, он может ссылаться на любой URL на вашем сайте. Однако, если ваш sitemap находится по адресу /content/sitemap.xml, он может ссылаться только на URL, начинающиеся с /content/.

Просмотр sitemap принимает дополнительный обязательный аргумент: {'sitemaps': sitemaps}. sitemaps должен быть словарем, который сопоставляет короткие метки разделов (например, blog или news) с их классами Sitemap (например, BlogSitemap или NewsSitemap). Он также может сопоставлять экземпляр класса Sitemap (например, BlogSitemap(some_var)).

Классы sitemap

Класс Sitemap — это простой класс Python, представляющий «раздел» записей в вашем sitemap. Например, один класс Sitemap может представлять все записи вашего блога, а другой — все события в вашем календаре событий.

В простейшем случае все эти разделы объединяются в один sitemap.xml, но также возможно использовать фреймворк для генерации индекса sitemap, который ссылается на отдельные файлы sitemap, по одному на раздел. (См. Создание индекса sitemap ниже.)

Классы Sitemap должны быть подклассами django.contrib.sitemaps.Sitemap. Они могут находиться в любом месте вашего кода.

Простой пример

Предположим, у вас есть система блога с моделью Entry и вы хотите, чтобы ваш sitemap включал все ссылки на ваши отдельные записи блога. Вот как может выглядеть ваш класс sitemap:

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() — это просто метод, возвращающий список объектов. Объекты, возвращенные этим методом, будут переданы любым вызываемым методам, соответствующим свойству sitemap (location, lastmod, changefreq и priority).
  • lastmod должен возвращать объект Python 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/'
  • Плохо: 'http://example.com/foo/bar/'

Если location не предоставлен, фреймворк вызовет метод get_absolute_url() для каждого объекта, возвращенного методом items().

Для указания протокола, отличного от 'http', используйте protocol.

lastmod

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

Если это метод, он должен принимать один аргумент — объект, возвращенный методом items() — и возвращать дату/время последнего изменения этого объекта в виде объекта Python datetime.datetime.

Если это атрибут, его значение должно быть объектом Python datetime.datetime, представляющим дату/время последнего изменения для каждого объекта, возвращенного методом items().

Если у всех элементов в карте сайта есть lastmod, карта сайта, сгенерированная методом views.sitemap(), будет иметь заголовок Last-Modified, равный последней lastmod. Вы можете активировать ConditionalGetMiddleware, чтобы Django корректно реагировал на запросы с заголовком If-Modified-Since, что предотвратит отправку карты сайта, если она не изменилась.

changefreq

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

Если это метод, он должен принимать один аргумент — объект, возвращенный методом items() — и возвращать частоту изменения этого объекта в виде строки Python.

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

Устарел начиная с версии 1.8: Используйте django.contrib.flatpages.sitemaps.FlatPageSitemap вместо этого.

Класс django.contrib.sitemaps.FlatPageSitemap анализирует все публично видимые flatpages, определенные для текущего SITE_ID (см. sites documentation) и создает запись в карте сайта. Эти записи включают только атрибут location — не lastmod, changefreq или priority.

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.core.urlresolvers 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 News. Предполагая, что 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

После добавления приложения 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.8/ref/contrib/sitemaps/

Spec-Zone.ru

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