Spec-Zone.ru › Django 1.9

Каркас сайта

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

Обзор

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

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

Он работает аналогично каркасу рассылки Django. Чтобы создать карту сайта, просто напишите класс 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')

Чтобы активировать генерацию карты сайта на вашем сайте 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.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 [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'),
]

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

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

После добавления приложения карт сайта в свой проект вы также можете отправить запрос 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.9/ref/contrib/sitemaps/

Spec-Zone.ru

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