Структура карты сайта
Django поставляется с высокоуровневой структурой для генерации карт сайта, которая упрощает создание XML-файлов карт сайта.
Обзор
Карта сайта — это 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
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. Этот набор данных будет использован для генерации элементов карты сайта. Он также может содержать запись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'),
]
Карта сайта для статических представлений
Часто вам необходимо, чтобы поисковые роботы индексировали представления, которые не являются страницами деталей объектов или плоскими страницами. Решением является явное указание имён 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:
changefreqitemlastmodlocationpriority
Атрибут 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.1/ref/contrib/sitemaps/