Фреймворк карты сайта
Django поставляется с фреймворком высокого уровня для генерации карты сайта, который упрощает создание XML-файлов карты сайта sitemap.
Обзор
Карта сайта — это XML-файл на вашем сайте, который сообщает поисковым индексаторам, как часто ваши страницы меняются и насколько «важны» определённые страницы по отношению к другим страницам вашего сайта. Эта информация помогает поисковым системам индексировать ваш сайт.
Фреймворк карт сайта Django автоматизирует создание этого XML-файла, позволяя вам выразить эту информацию в коде Python.
Он работает очень похоже на фреймворк синдикации Django. Чтобы создать карту сайта, просто напишите класс Sitemap и укажите на него в вашем URLconf.
Установка
Чтобы установить приложение карты сайта, выполните следующие действия:
- Добавьте
'django.contrib.sitemaps'в настройкуINSTALLED_APPS. - Убедитесь, что ваша настройка
TEMPLATESсодержит бэкендDjangoTemplates, где параметрAPP_DIRSустановлен наTrue. Он включён по умолчанию, поэтому вам нужно изменить это только в том случае, если вы изменили эту настройку. - Убедитесь, что вы установили
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:
changefreqitemlastmodlocationpriority
Атрибут 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/