Создаем в Django карту сайта Sitemap.xml


17 января 2021


Создание карты сайта Sitemap.xml во фреймворке Django

Один из принципов оптимизации сайта для поисковых систем - это создание карты сайта Sitemap. Благодаря этой странице поисковые системы узнают какие страницы были обновлены или созданы. В Django уже существуют встроенные механизмы для создания таких карт в формате XML. В рамках этой статьи мы рассмотрим как создать такую карту на основе существующих моделей или и для прямых ссылок с помощью urls.py.

 

Подготовка тестового проекта

У вас уже должен быть установлен Django. С помощью следующей команды мы создадим проект с названием 'django_project':

django-admin startproject django_project

В это проекте мы создадим приложение:

cd django_project
python manage.py startapp mapapp

Это приложение мы должны добавить в файл 'settings.py' в 'INSTALLED_APPS':

vim django_project/settings.py
'mapapp.apps.MapappConfig'

Добавление приложения в Django

Что бы наше приложение имело свой собственный файл маршрутов (urls.py) мы должны расширить основной файл добавив в него метод 'include':

vim django_project/urls.py
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('mapapp.urls')),
]

Расширение urls.py через include в Django

В папке 'mapapp' создадим файл 'urls.py', который будет содержать маршруты и функции. Их мы создадим позже:

vim mapapp/urls.py
from django.urls import path
from .views import about, news

urlpatterns = [
    path('about/', about, name='about-page'),
    path('news/<pk>/', news, name='news-page'),
]

Создадим модель с методом get_absolute_url(), который будет возвращать прямую ссылку на каждый из созданных объектов:

vim mapapp/models.py
from django.db import models

class NewsModel(models.Model):
    title = models.CharField(max_length=120)
    url = models.CharField(max_length=140)
    date = models.DateField()

    def get_absolute_url(self):
        return f'/{self.pk}'

Проведем миграции:

python manage.py makemigrations
python manage.py migrate

Создание вьюшек не обязательно, но у вас могут появиться ошибки так как они импортируются в urls.py. Для примера можно создать следующие:

from django.shortcuts import render, HttpResponse
from .models import News

def about(request):
    return HttpResponse('Hello 1')

def news(request):
    return HttpResponse(News.objects.get(id=pk).title)

Вы можете добавить данные в базу используя shell или панель администрирования.

 

Создание карты сайта

Для создания карты сайта используется приложение 'django.contrib.sitemaps'. Что бы его можно было использовать мы так же должны добавить его в 'INSTALLED_APPS':

vim django_project/settings.py
'django.contrib.sitemaps'

Добавление приложения sitemap.xml в INSTALLED_APPS в Django

Это приложение не нуждается в дополнительных таблицах в базе данных, поэтому миграции выполнять не нужно

Все классы, через которые мы будем объявлять карты для сайта, принято создавать в каталоге приложения для которого эта карта создается. В этом каталоге создается файл sitemap.py:

vim myapp/sitemap.py

Логически мы можем разделить страницы нашего сайта на 2 типа:

  • Статические страницы - например страницы "О компании", всегда хранящееся по ссылке 'about/' или имеющая аналогичное имя. Url этой страницы статичный и не берется из базы;
  • Для динамических страниц - например товары или новости. Каждая ссылка новости состоит из какого-то слова и значения из базы. В urls.py обычно они выглядят как 'news/<pk>/'.

Что бы мы могли создавать карту нужно использовать классы унаследованные от Sitemap. В этих классах мы обязаны определить 2 метода:

  • items - представляет собой объект для создания ссылки. Не важно какой тип данных тут находится;
  • location - генерирует ссылку из части items.

Для статической страницы 'about/' класс sitemap будет выглядеть следующим образом:

from django.contrib.sitemaps import Sitemap
from django.shortcuts import reverse

class StaticViewSitemap(Sitemap):

    def items(self):
        return ['about-page']

    def location(self, item):
        return reverse(item)

Если мы хотим создать sitemap из динамических данных, url которых состоит из значений базы данных, то можем использовать следующий способ:

from django.contrib.sitemaps import Sitemap
from .models import News
from django.shortcuts import reverse

class DynamicViewSitemap(Sitemap):

    def items(self):
        return News.objects.all()

    def location(self, item):
        # return reverse('news-page', args=[item.pk])
        return f'/news/{item.pk}/'

При этом location, в случае работы с моделью, можно не указывать если у вас создан метод get_absolute_url().

urls.py

Что бы вывести результат работы этих классов в виде xml объектов мы должны объединить их в словаре и связать c url:

vim mapapp/urls.py
from django.urls import path
from .views import about, news
from .sitemap import StaticViewSitemap, DynamicViewSitemap
from django.contrib.sitemaps.views import sitemap

sitemaps = {
    'static': StaticViewSitemap,
    'dynamic': DynamicViewSitemap
}

urlpatterns = [
    path('about/', about, name='about-page'),
    path('news/<int:pk>/', news, name='news-page'),
    path('sitemap.xml', sitemap, {'sitemaps': sitemaps}),
]

Добавление карт сайта sitemap.xml в urls.py Django

Результат мы можем увидеть при запуске сервера:

sitemap.xml в Django

Поисковые системы работают по-разному. В основном все поисковые системы будут относить карту сайта созданную по пути '/news/sitemap.xml' к самому адресу 'news'. Каждую из карт сайта может проиндексировать сама поисковая система либо она может быть добавлена руками в панели вебмастера. Кроме этого и частоту проверки чтения sitemap, у некоторых поисковых систем, так же можно изменить.

Формат sitemap подразумевает следующие дополнительные данные, которые может прочитать поисковая система:

  • lastmod - дата и время изменения страницы (формат datetime);
  • changefreq - частота изменения страницы;
  • priority - приоритет по которому поисковик будет обходить эту ссылку (значение от 0.0 до 1.0);
  • limit - лимит на количество ссылок в одной карте (по умолчанию 5000).

changefreq и priority

Пример использования этих возможностей:

from django.contrib.sitemaps import Sitemap
from django.shortcuts import reverse

1

priority и changefreq в sitemap.xml в Django

Changefreq может принимать следующие значения:

  • 'always'
  • 'hourly'
  • 'daily'
  • 'weekly'
  • 'monthly'
  • 'yearly'
  • 'never'

lastmod

Для вывода lastmod мы должны объявить функцию возвращающую объект datetime. В модели мы создавали поле такое поле - используем его:

from django.contrib.sitemaps import Sitemap

class DynamicViewSitemap(Sitemap):

    def items(self):
        return News.objects.all()

    def location(self, item):
        return f'/news/{item.pk}/'

    def lastmod(self, item):
        return item.date

lastmod в sitemap.xml в Django

...

Теги: #python #django #sitemap


Популярные тэги
О блоге
Этот блог представляет собой конспекты выученного материала, преобретенного опыта и лучшие практики в системном администрировании и программировании.