Структура карты сайта¶
Django поставляется с высокоуровневой структурой создания карты сайта для создания XML-файлов sitemap.
Обзор¶
Карта сайта — это XML-файл на вашем веб-сайте, который сообщает индексаторам поисковых систем, как часто изменяются ваши страницы и насколько «важны» определенные страницы по отношению к другим страницам вашего сайта. Эта информация помогает поисковым системам индексировать ваш сайт.
Платформа карты сайта Django автоматизирует создание этого XML-файла, позволяя выразить эту информацию в коде Python.
Он работает во многом похоже на фреймворк синдикации от Django. Чтобы создать карту сайта, напишите класс Sitemap и укажите его в вашем URLconf.
Установка¶
Чтобы установить приложение Sitemap, выполните следующие действия:
Добавьте ``“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. Они могут жить где угодно в вашей кодовой базе.
Пример¶
Предположим, у вас есть система блогов с моделью «Запись», и вы хотите, чтобы ваша карта сайта включала все ссылки на отдельные записи вашего блога. Вот как может выглядеть ваш класс карты сайта:
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()— это метод, который возвращает последовательность илиQuerySetобъектов. Возвращенные объекты будут переданы любым вызываемым методам, соответствующим свойству карты сайта (location,lastmod,changefreqиpriority).lastmodдолжен возвращатьdatetime.В этом примере нет метода
location, но вы можете предоставить его, чтобы указать URL-адрес вашего объекта. По умолчаниюlocation()вызываетget_absolute_url()для каждого объекта и возвращает результат.
Ссылка на класс Sitemap¶
- class Sitemap¶
Класс Sitemap может определять следующие методы/атрибуты:
- items¶
Обязательный. Метод, возвращающий последовательность или
QuerySetобъектов. Среду не волнует, какой тип объектов они представляют; все, что имеет значение, это то, что эти объекты передаются методамlocation(),lastmod(),changefreq()иpriority().
- location¶
Необязательно. Либо метод, либо атрибут.
Если это метод, он должен возвращать абсолютный путь к данному объекту, возвращаемый
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, который предотвратит отправку карты сайта, если она не изменилась.
- paginator¶
Необязательный.
Это свойство возвращает
Paginatorдляitems(). Если вы создаете карты сайта в пакетном режиме, вы можете переопределить это свойство как кэшированное, чтобы избежать множественных вызововitems().
- changefreq¶
Необязательно. Либо метод, либо атрибут.
Если это метод, он должен принимать один аргумент — объект, возвращаемый
items()— и возвращать частоту изменения этого объекта в виде строки.Если это атрибут, его значение должно быть строкой, представляющей частоту изменения каждого объекта, возвращаемого
items().Возможные значения
changefreq, независимо от того, используете ли вы метод или атрибут:'всегда''почасово''ежедневно''еженедельно''ежемесячно''ежегодно''никогда'
- priority¶
Необязательно. Либо метод, либо атрибут.
Если это метод, он должен принимать один аргумент — объект, возвращаемый
items()— и возвращать приоритет этого объекта в виде строки или числа с плавающей запятой.Если это атрибут, его значение должно быть либо строкой, либо числом с плавающей точкой, представляющим приоритет каждого объекта, возвращаемого
items().Примеры значений
priority:0.4,1.0. Приоритет страницы по умолчанию — «0,5». Дополнительную информацию см. в документации sitemaps.org.
- protocol¶
Необязательный.
Этот атрибут определяет протокол («http» или «https») URL-адресов в карте сайта. Если он не установлен, используется протокол, с помощью которого была запрошена карта сайта. Если карта сайта создается вне контекста запроса, по умолчанию используется https.
Changed in Django 5.0:В более старых версиях протоколом по умолчанию для карт сайта, созданных вне контекста запроса, был http.
- limit¶
Необязательный.
Этот атрибут определяет максимальное количество URL-адресов, включенных в каждую страницу карты сайта. Его значение не должно превышать значение по умолчанию «50000», которое является верхним пределом, разрешенным в протоколе Sitemaps <https://www.sitemaps.org/protocol.html#index>`_.
- i18n¶
Необязательный.
Логический атрибут, который определяет, должны ли URL-адреса этой карты сайта создаваться с использованием всех ваших
LANGUAGES. По умолчанию установлено значение «Ложь».
- languages¶
Необязательный.
последовательность кодов языка для использования для создания альтернативных ссылок, когда
i18nвключен. По умолчанию:LANGUAGES.
- alternates¶
Необязательный.
Логический атрибут. При использовании в сочетании с
i18nкаждый сгенерированный URL-адрес будет иметь список альтернативных ссылок, указывающих на другие языковые версии с использованием атрибута hreflang. По умолчанию установлено значение «Ложь».
- x_default¶
Необязательный.
Логический атрибут. Когда
True, альтернативные ссылки, сгенерированныеalternates, будут содержать резервную записьhreflang="x-default"со значениемLANGUAGE_CODE. По умолчанию установлено значение «Ложь».
- get_latest_lastmod()¶
Необязательно. Метод, возвращающий последнее значение, возвращенное
lastmod. Эта функция используется для добавления атрибута «lastmod» к переменным контекста индекса карты сайта.По умолчанию
get_latest_lastmod()возвращает:Если
lastmodявляется методом: последнийlastmodвозвращается путем вызова метода со всеми элементами, возвращаемымиSitemap.items().
- get_languages_for_item(item)¶
Необязательно. Метод, возвращающий последовательность языковых кодов, для которых отображается элемент. По умолчанию
get_languages_for_item()возвращаетlanguages.
Ярлыки¶
Платформа карты сайта предоставляет удобный класс для обычного случая:
- class GenericSitemap(info_dict, priority=None, changefreq=None, protocol=None)¶
Класс
django.contrib.sitemaps.GenericSitemapпозволяет вам создать карту сайта, передав ей словарь, который должен содержать как минимум записьqueryset. Этот набор запросов будет использоваться для создания элементов карты сайта. Он также может иметь запись date_field, которая определяет поле даты для объектов, полученных из набора запросов. Это будет использоваться для атрибутаlastmodи методовget_latest_lastmod()в сгенерированной карте сайта.Аргументы ключевых слов
priority,changefreqиprotocolпозволяют указать эти атрибуты для всех URL-адресов.
Пример¶
Вот пример 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')¶
Платформа карты сайта также имеет возможность создавать индекс карты сайта, который ссылается на отдельные файлы карты сайта, по одному на каждый раздел, определенный в вашем словаре карты сайта. Единственные различия в использовании:
В конфигурации URL вы используете два представления:
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},
name="django.contrib.sitemaps.views.index",
),
path(
"sitemap-<section>.xml",
views.sitemap,
{"sitemaps": sitemaps},
name="django.contrib.sitemaps.views.sitemap",
),
]
Это автоматически создаст файл sitemap.xml, который ссылается как на sitemap-flatpages.xml, так и на sitemap-blog.xml. Классы Sitemap и атрибут sitemaps вообще не изменяются.
Если все карты сайта имеют lastmod, возвращаемый Sitemap.get_latest_lastmod(), индекс карты сайта будет иметь заголовок Last-Modified, равный последнему lastmod.
Вам следует создать индексный файл, если одна из ваших карт сайта содержит более 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"},
name="django.contrib.sitemaps.views.index",
),
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 представляет собой список объектов, содержащих атрибуты location иlastmod для каждой карты сайта. Каждый URL-адрес предоставляет следующие атрибуты:
location: местоположение (URL и страница) карты сайта.lastmod: заполняется методомget_latest_lastmod()для каждой карты сайта.
Карта сайта¶
Переменная urlset представляет собой список URL-адресов, которые должны отображаться в карте сайта. Каждый URL-адрес предоставляет атрибуты, определенные в классе Sitemap:
заместителиchangefreqпредметластмодместоположениеприоритет
Атрибут alternates доступен, когда i18n и alternates включены. Это список других языковых версий, включая необязательный резервный вариант x_default для каждого URL-адреса. Каждый альтернативный вариант представляет собой словарь с ключами location и lang_code.
Атрибут item был добавлен для каждого URL-адреса, чтобы обеспечить более гибкую настройку шаблонов, таких как карты сайта новостей Google`_. Предположим, что :attr:`~Sitemap.items()` карты сайта вернет список элементов с ``publication_data и полем tags, что-то вроде этого создаст карту сайта, совместимую с Google News:
<?xml version="1.0" encoding="UTF-8"?>
<urlset
xmlns="https://www.sitemaps.org/schemas/sitemap/0.9"
xmlns:news="https://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>