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

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

6.1 Работа с URL
3 из 3 шагов пройдено

Создание дружественных для поисковой оптимизации URL-адресов постов

Канонический URL-адрес представления детальной информации о посте блога в настоящее время выглядит как /blog/1/.

Мы изменим шаблон URL-адреса, чтобы формировать дружественные для поисковой оптимизации URL-адреса постов.

В целях формирования URL-адресов одиночных постов мы будем использовать дату публикации publish и значения slug.

Присоединив даты, мы приведем URL-адрес детальной информации о посте к следующему виду: /blog/2022/1/1/who-was-django-reinhardt/. Мы предоставим поисковым механизмам дружественные для индексации URL-адреса, содержащие как заголовок, так и дату поста.

Для того чтобы получить одиночные посты с комбинацией даты публикации и слага, необходимо обеспечить, чтобы ни одну запись невозможно было сохранить в базе данных с тем же значением поля slug и поля publish, что и у существующего поста.

Мы предотвратим хранение в модели Post дублирующихся записей, определив, что слаги являются уникальными для даты публикации поста.

Отредактируйте файл models.py, добавив следующий ниже параметр unique_for_date в поле slug модели Post:

class Post(models.Model):

# ...

    slug = models.SlugField(max_length=250,
                            unique_for_date='publish')

# ...

Теперь при использовании параметра unique_for_date поле slug должно быть уникальным для даты, сохраненной в поле publish.

Обратите внимание, что поле publish является экземпляром класса DateTimeField, но проверка на уникальность значений будет выполняться только по дате (не по времени).

Django будет предотвращать сохранение нового поста с тем же именем, что и у существующего поста на заданную дату публикации. В результате мы обеспечили уникальность слагов для даты публикации, поэтому теперь можно извлекать одиночные посты по полям publish и slug.

Мы изменили модели, поэтому давайте создадим миграции. Обратите внимание, что параметр unique_for_date не соблюдается на уровне базы данных, поэтому миграция базы данных не требуется.

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

Выполните следующую ниже команду в командной оболочке: 

python manage.py makemigrations blog

 Вы должны получить следующий ниже результат:

Migrations for 'blog':
    blog/migrations/0002_alter_post_slug.py
    – Alter field slug on post

Django только что создал файл 0002_alter_post_slug.py внутри каталога migrations приложения blog.

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

python manage.py migrate

 Django будет считать, что все миграции были применены и модели синхронизированы. В базе данных не будет выполнено никаких действий, поскольку параметр unique_for_date не применяется на уровне базы данных.

 

Видоизменение шаблонов URL-адресов

Давайте видоизменим шаблоны URL-адресов, чтобы использовать дату публикации и слаг для URL-адреса детальной информации о посте.

Отредактируйте файл urls.py приложения blog, заменив строку:

path('<int:id>/', views.post_detail, name='post_detail'),

строками:

path('<int:year>/<int:month>/<int:day>/<slug:post>/',
      views.post_detail,
      name='post_detail'),

Теперь файл urls.py должен выглядеть следующим образом:

from django.urls import path
from . import views

app_name = 'blog'

urlpatterns = [
    # представления поста
    path('', views.post_list, name='post_list'),
    path('<int:year>/<int:month>/<int:day>/<slug:post>/',
         views.post_detail,
         name='post_detail'),
]

Шаблон URL-адреса представления post_detail принимает следующие
ниже аргументы:

  • year: требуется целое число;
  • month: требуется целое число;
  • day: требуется целое число;
  • post: требуется слаг (строка, содержащая только буквы, цифры, знаки подчеркивания или дефисы).

Конвертор пути int используется для параметров year, month и day, тогда как конвертор пути slug применяется для параметра post.

Все предоставляемые фреймворком Django конверторы путей можно посмотреть на странице https://docs.djangoproject.com/en/5.0/topics/http/urls/#path-converters.


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

Объясните пожалуйста, в чем же заключается дружелюбность такой реализации?

@Aleksandr_Bogatyrev, в дружелюбии поисковых систем, это относится к SEO. У нас же написано в этой лекции -  "Мы изменим шаблон URL-адреса, чтобы формировать дружественные для поисковой оптимизации URL-адреса постов."

@Илья_Перминов, Если честно такая вложенность страницы не очень то дружелюбна к SEO. Как правило делают  "site.ru/blog/category/postname" или "site.ru/postname-1" (1=id). Пример можно взять с популярным сайтов блогов/новостников, там плюс/минус такая структура адреса страницы.

Изменен Олег Пешков

@Олег_Пешков, Я полностью согласен с вами, в данном случае мы как раз и уходим от ссылок типа "/blog/1/" к добавлению слагов. Добавление даты, это лишь пример как добавить дату в адрес станицы.

Получается если я введу /blog/2022/ то у меня отобразятся все записи за 2022 год?

И почему всё время ругается на мой таймзон?

WARNINGS:
blog.Posts.publish: (fields.W161) Fixed default value provided.
        HINT: It seems you set a fixed date / time / datetime value as default for this field. This may not be what you want. If you want to have the current date as default, use `djan
go.utils.timezone.now`
 

 

 

 Такой сеттинг тоже не помог

Изменен Ravshan Battalov

@Ravshan_Battalov, Нет, в данном случае мы просто показываем как работать с адресами, и что туда можно добавить. По поводу таймзона, скиньте что у вас в поле publish модели Post.

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

publish = models.DateTimeField(default=timezone.now())

@Ravshan_Battalov, А нужно вот так:

publish = models.DateTimeField(default=timezone.now)