Django 5 для начинающих

Прогресс по курсу:  9/1004

6.9 Добавление карты сайта
1 из 1 шага пройден

Добавление карты сайта

Django идет в комплекте с фреймворком карт сайтов, который позволяет динамически создавать карты для своего сайта.

Карта сайта – это XML-файл, который сообщает поисковым системам о страницах веб-сайта, их релевантность и частоту их обновления. Использование карты сделает сайт более заметным в рейтинге поисковых систем, поскольку она помогает поисковым роботам индексировать содержимое сайта.

Фреймворк карты сайта в Django зависит от приложения django.contrib.sites, которое позволяет ассоциировать объекты с теми или иными веб-сайтами, работающими вместе с вашим проектом. Это удобно, когда вы хотите управлять несколькими сайтами, используя один проект Django.

Для установки фреймворка карт сайтов необходимо активировать приложения sites и sitemap в своем проекте.

Отредактируйте файл settings.py проекта, добавив django.contrib.sites и django.contrib.sitemaps в настроечный параметр INSTALLED_APPS.

Кроме того, определите новый настроечный параметр для SITE_ID, как показано ниже:

SITE_ID = 1

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'blog.apps.BlogConfig',
    'taggit',
    'django.contrib.sites',
    'django.contrib.sitemaps',
]

Теперь запустите следующую ниже команду из командной оболочки, что-бы создать таблицы приложения Django sites в базе данных:

python manage.py migrate

Вы должны увидеть результат, содержащий такие строки:

Теперь приложение sites синхронизировано с базой данных.

Затем внутри каталога своего приложения blog создайте новый файл и назовите его sitemaps.py.
Откройте файл и добавьте в него следующий ниже исходный код:

from django.contrib.sitemaps import Sitemap
from .models import Post


class PostSitemap(Sitemap):
    changefreq = 'weekly'
    priority = 0.9

    def items(self):
        return Post.published.all()

    def lastmod(self, obj):
        return obj.updated

Мы определили конкретно-прикладную карту сайта, унаследовав класс Sitemap модуля sitemaps.

Атрибуты changefreq и priority указывают частоту изменения страниц постов и их релевантность на веб-сайте (максимальное значение равно 1).

Метод items() возвращает набор запросов QuerySet объектов, подлежащих включению в эту карту сайта. По умолчанию Django вызывает метод get_absolute_url() по каждому объекту, чтобы получить его URL-адрес.

Напомним, что мы применили этот метод в разделе 6.1 "Работа с URL", чтобы формировать канонический URL-адрес постов. Если нужно указать URL-адрес каждого объекта, то в класс sitemap можно добавить метод location.

Метод lastmod получает каждый возвращаемый методом items() объект и возвращает время последнего изменения объекта. Атрибуты changefreq и priority могут быть либо методами, либо атрибутами.

С полным справочным материалом по картам сайтов можно ознакомиться в официальной документации Django на странице https://docs.djangoproject.com/en/5.0/ref/contrib/sitemaps/.

Мы создали карту сайта. Теперь необходимо создать для него URL-адрес.

Отредактируйте главный файл urls.py проекта mysite, добавив карту сайта, как показано ниже:

from django.urls import path, include
from django.contrib import admin
from django.contrib.sitemaps.views import sitemap
from blog.sitemaps import PostSitemap

sitemaps = {
    'posts': PostSitemap,
}

urlpatterns = [
    path('admin/', admin.site.urls),
    path('blog/', include('blog.urls', namespace='blog')),
    path('sitemap.xml', sitemap, {'sitemaps': sitemaps},
         name='django.contrib.sitemaps.views.sitemap')
]

В приведенном выше исходном коде были вставлены необходимые инструкции импорта и определен словарь sitemaps.

На сайте может быть определено несколько карт. Мы определили шаблон URL-адреса, который совпадает с шаблоном sitemap.xml и в котором используется встроенное в Django представление sitemap. Словарь sitemaps передается в представление sitemap.

Следующей ниже командой запустите сервер разработки и перейдите по URL-адресу http://127.0.0.1:8000/sitemap.xml в своем браузере.

Вы увидите результат в формате XML, включающий все опубликованные посты, как показано ниже:

URL-адрес каждого объекта Post формируется путем вызова его метода get_absolute_url().

Атрибут lastmod соответствует полю даты updated поста, как было указано в карте сайта, а атрибуты changefreq и priority также взяты из класса Post-Sitemap.

Для формирования URL-адресов используется домен example.com. Этот домен получен из хранящегося в базе данных объекта Site. Указанный объект был создан по умолчанию, когда вы синхронизировали фреймворк сайтов со своей базой данных.

Подробнее о фреймворке сайтов можно почитать на странице https://docs.djangoproject.com/en/5.0/ref/contrib/sites/.

Пройдите по URL-адресу http://127.0.0.1:8000/admin/sites/site/ в своем браузере. Вы должны увидеть что-то вроде этого:

На рисунке показано представление списка на сайте администрирования для фреймворка сайтов. Здесь можно задать домен или хост, который будет использоваться фреймворком сайтов и зависящими от него приложениями.

Для того чтобы сгенерировать URL-адреса, существующие в локальной среде, измените доменное имя на localhost:8000, как показано и сохраните его:

Снова пройдите по URL-адресу http://127.0.0.1:8000/sitemap.xml в своем браузере.

Теперь в отображаемых в ленте URL-адресах будет использоваться новое хост-имя, и они будут выглядеть вот так: http://localhost:8000/blog/2022/1/22/markdown-post/.

Теперь ссылки доступны в локальной среде. В производственной среде, чтобы иметь возможность генерировать абсолютные URL-адреса, придется использовать домен своего веб-сайта.


  • Комментариев
Будьте вежливы и соблюдайте наши принципы сообщества. Пожалуйста, не оставляйте решения и подсказки в комментариях, для этого есть отдельный форум.
Оставить комментарий

Хмм. Не сразу понял для чего SITE_ID нужен. Интересно. Оставлю это тут https://habr.com/ru/articles/530766/

Но какой смысл хранить все в одной базе для разных сайтов пока не осознал. Неужели в реальных проектах это корректный подход для хранения данных.

@Антон_Глухенко,  я еще и не понял в целом зачем она нам тут нужна, если это если есть разные сайты, а сайт то у нас один

Напомним, что мы применили этот метод в разделе 7.1 "Работа с URL"

 все съехало же

@Никита_Ильин, Спасибо, поправили.

В модели Post есть метод get_absolute_url, который должен вызываться методов update, но все равно ошибка

@Михаил_Зайнутдинов, Можете загрузить свой проект по ссылке - https://mega.nz/filerequest/rANtUqzWHQ4

Попробуем разобраться.

@Илья_Перминов, Загрузил, спасибо!

@Михаил_Зайнутдинов, так как вы изменили модель у блога, то в sitemaps.py вам нужно поменять функцию:

    def lastmod(self, obj):
        return obj.edited_at

И еще, если я не ошибаюсь, то пароль от почтового сервера без пробелов нужно писать в EMAIL_HOST_PASSWORD.

@Илья_Перминов, Понял, спасибо!

@Илья_Перминов,  у меня тоже ругался на "updated".

Но после того как в sitemaps.py исправил:

def lastmod(self, obj):
    return obj.updated

на:

def lastmod(self, obj):
    return obj.update

всё заработало.

Может в конспекте это стоит проверить и если надо, то поправить?

Пардон, беру свои слова обратно.

Проверил у себя в модели и обнаружил, что вместо "updated" было "update" из-за чего и выскакивало исключение. 

Вопрос снят :-)

Почему то не работает карта сайта

Проверьте пожалуйста ещё раз, все ли из лекции вы выполнили. Должно работать.
В этом то и дело, что вроде все сделал, а не работает (

@Кислинский_Роман, В settings.py добавили 

SITE_ID = 1

 И после выполнили миграции? Если все это сделали, то можете на почту perminoff-ilya@yandex.ru скинуть свой проект, посмотрим.

@Илья_Перминов, Cпасибо, все заработало)

очень полезная инфа, спс!

Всем привет, а как добавить в sitemap другие странички, например если я сделал приложение contact и там рендерится страничка с текстом и формой обратной связи, ее хочется как-то туда запихнуть. А также как добавить корень сайта в sitemap?

@Михаил_Тевелев, Вот по такому принципу - https://docs.djangoproject.com/en/4.2/ref/contrib/sitemaps/#sitemap-for-static-views мы можем добавлять любые страницы, в том числе и корень сайта. Но нужно будет добавлять 2 класса, один для динамических страниц, второй для статики.

Изменен Илья Перминов

@Илья_Перминов, ага, спасибо, разобрался.

А всем у кого будет такой же вопрос, решение простое. В файле sitemaps.py:

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

from blog.models import Post


class StaticViewSitemap(Sitemap):
    priority = 0.5
    changefreq = 'monthly'

    def _items(self):
        return ['index:index', 'contact:contact']

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


class PostSitemap(Sitemap):
    changefreq = "weekly"
    priority = 0.9

    def items(self):
        return Post.published.all()

    def lastmod(self, obj):
        return obj.updated

В основном urls.py все это соединяем в один поток:

sitemaps = {
    'static': StaticViewSitemap,
    'posts': PostSitemap,
}

И вставляем в urlpatterns:

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

    ...

    path('sitemap.xml', sitemap, {'sitemaps': sitemaps}, name='django.contrib.sitemaps.views.sitemap')
]

SITE_ID = 1 
незаметная строчка в сеттингах

Скажите пожалуйста, так ли должна выглядеть sitemap?

@Руслан_Гаджиев, да, всё верно.

@Дмитрий_Селезнев, спасибо!)

После смены имени на localhost:8000 и переходе по ссылке такой результат у меня 

@Дмитрий_Чекмасов, Странно, еще раз проверил, сайт должен работать на http://127.0.0.1:8000 и на http://localhost:8000 одинаково. А точно по этому url есть пост если переходить через http://127.0.0.1:8000?

@Илья_Перминов, Не понял вопроса, все делал как было в предыдущих шагах

@Илья_Перминов, ни по одной ссылке не показывает

@Дмитрий_Чекмасов, Давайте подробнее тогда, до этого у вас блог был по адресу http://127.0.0.1:8000? И когда вы изменили в админ панели адрес сайта на localhost:8000 и нажали сохранить, то больше вас не пускает ни по одному адресу на сайт?

@Илья_Перминов, вроде разобрался, неправильно понял возможно, в общем оба варианта работают, например  http://localhost:8000/blog/ или  http://127.0.0.1:8000/admin/, но эта ссылка не находит старницу

Я правильно понял что она по сути индивидуальна в зависимости от созданных постов?

@Дмитрий_Чекмасов, да, это на моем примере такая ссылка. Тут основной смысл в том, что в карте сайта были адреса с доменным именем example.com по дефолту, а мы, через админ панель, можем его поменять на наше доменное имя, пока это localhost.

У меня почему то XML файл выглядит вот так

@Ilia_Boiarintsev, не пробовали html-код посмотреть?

@Дмитрий_Селезнев, все понял, такое отображение только в Safari