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

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

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

Использование канонических URL-адресов для моделей

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

Канонический URL-адрес – это предпочтительный URL-адрес ресурса. Его можно представить как URL-адрес наиболее репрезентативной страницы с конкретным контентом.

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

Канонические URL-адреса позволяют указывать URL-адрес мастер-копии страницы. Django дает возможность в своих собственных моделях реализовывать метод get_absolute_url(), который возвращает канонический URL-адрес объекта.

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

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

Мы будем использовать функцию утилиту reverse() модуля django.urls.

Отредактируйте файл models.py приложения blog, импортировав функцию reverse() и добавив метод get_absolute_url() в класс Post, как показано ниже:

from django.urls import reverse
class Post(models.Model):

............


    def get_absolute_url(self):
        return reverse('blog:post_detail',
                       args=[self.id])

Функция reverse() будет формировать URL-адрес динамически, применяя имя URL-адреса, определенное в шаблонах URL-адресов.

Мы использовали именное пространство blog, за которым следуют двоеточие и URL-адрес post_detail.

Напомним, что именное пространство blog определяется в главном файле urls.py проекта при вставке шаблонов URL-адресов из blog.urls.

URL-адрес post_detail определен в файле urls.py приложения blog. Результирующий строковый литерал, blog:post_detail, можно использовать глобально в проекте, чтобы ссылаться на URL-адрес детальной информации о посте.

Этот URL-адрес имеет обязательный параметр – id извлекаемого поста блога. Идентификатор id объекта Post был включен в качестве позиционного аргумента, используя параметр args=[self.id].

Подробнее о функциях-резольверах URL-адресов можно узнать на странице https://docs.djangoproject.com/en/5.0/ref/urlresolvers/.

Давайте заменим URL-адреса детальной информации о посте в шаблонах новым методом get_absolute_url().

Отредактируйте файл blog/post/list.html, заменив строку:

<a href="{% url 'blog:post_detail' post.id %}">

строкой:

<a href="{{ post.get_absolute_url }}">

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

{% extends "blog/base.html" %}
{% block title %}My Blog{% endblock %}
{% block content %}
    <h1>My Blog</h1>
    {% for post in posts %}
        <h2>
            <a href="{{ post.get_absolute_url }}"> {{ post.title }}</a>
        </h2>
        <p class="date">
            Published {{ post.publish }} by {{ post.author }}
        </p>
        {{ post.body|truncatewords:30|linebreaks }}
    {% endfor %}
{% endblock %}

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

python manage.py runserver

Пройдите по URL-адресу http://127.0.0.1:8000/blog/ в своем браузере.

Ссылки на одиночные посты блога по-прежнему должны работать. Теперь Django формирует их, используя метод get_absolute_url() модели Post.


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

Если кому то не понятно, что же подразумевается под "каноническим URL"

Что такое canonical URL

Тег canonical URL был создан для решения проблемы дублирования страниц. В большинстве случаев для решения этой задачи лучше всего использовать редирект. Но, когда мы не можем использовать 301 редиректы, либо нам нужны страницы, которые будут просматриваться пользователями, тогда нам поможет атрибут rel=”canonical”.

Каноническим называется URL страницы, которую роботы Google считают главной среди нескольких ее вариантов на вашем сайте. Например, если одна и та же страница размещена по нескольким URL, таким как example.com?dress=1234 и example.com/dresses/1234, одна из версий будет выбрана в качестве канонической. Обратите внимание, что страницы могут быть не полностью идентичными. Они могут различаться, например, настройками фильтров или сортировки (сортировка по цене или фильтрация товаров по цвету не делают страницу уникальной). Домен канонической страницы может отличаться от домена дубликата.
Справка Google Search Console

Источник:https://sitechecker.pro/ru/what-is-canonical-url/

Очень сложно описана довольно простая тема ( 

Из текста мало что понятно, хорошо что интуитивно понятно как работает reverse.

@Dmitrii_Novozhilov, Согласен. Думаю в ближайшее время поправим.

Думаю, автор будет не против, если я оставлю здесь ссылку на русскоязычную документацию: https://django.fun/ru/docs/django/4.1/ref/urlresolvers/

@Олег_Якушев

Очень походе на машинный перевод. Некоторые фразы настолько завёрнутые, что понять их неполучается никак.

Лучше читать оргинал, он намного понятнее.

Бесспорно, я тоже читаю на английском обычно, но может кому то удобнее будет на ру, тем более там ещё по Джанго ресту, фласку и всяким паттернам есть переводы.

Я так и не понял для чего нужен параметр namespace в urls (namespace='blog') и для чего нужен app_name в blog/urls (app_name='blog'), а точнее что за что отвечает? Просто в материале написано, что "использовали именное пространство", но и без него всё работает, а вот без app_name даже сервер не запускается, выдаёт ошибку.
Помогите разобраться.

@Александр_Ёлшинnamespace это пространство имён, обычно используется чтоб объединить маршруты по группам, иначе придётся использовать уникальные имена маршрутов, а маршрутов может быть очень много. Да и просто удобнее пользоваться, когда наглядно видно к какой группе(пространству имён) принадлежит имя маршрута.

app_name='blog' задаёт имя приложения в файле urls, оно обязательно если планируется использовать пространство имён.

include('blog.urls', namespace='blog') задаёт имя пространства имён, можно указать любое, или можно не указывать, тогда имя пространства имён будет как указано в app_name.

Тоже не врубился, несколько раз перечитав. Может кому поможет:
 

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

В Django можно указать канонический URL-адрес для любого объекта модели, добавив в модель метод get_absolute_url(), который возвращает канонический URL-адрес объекта. Этот метод может использовать функцию reverse(), чтобы получить URL-адрес по имени URL-паттерна и аргументам. Например, если у нас есть модель Post с полем slug, мы можем определить канонический URL-адрес для поста так:

from django.db import models
from django.urls import reverse

class Post(models.Model):
# поля модели
slug = models.SlugField(max_length=250, unique=True)

def get_absolute_url(self):
# возвращает канонический URL-адрес поста по имени URL-паттерна и аргументу slug
return reverse('blog:post_detail', args=[self.slug])

Также можно указать канонический URL-адрес для любой страницы, добавив в шаблон тег <link rel="canonical" href="{{ canonical_url }}">, где canonical_url - это переменная, содержащая канонический URL-адрес страницы. Этот тег сообщает поисковикам, какой URL-адрес считать главным для данной страницы.

И самое главное, ЗАЧЕМ: 


 Канонический URL-адрес нужен для того, чтобы избежать проблем с дублированием контента на сайте и повысить эффективность SEO-оптимизации. Дублирование контента может возникать, когда одна и та же страница доступна по разным URL-адресам, например, из-за разных параметров, версий или редиректов. Это может снизить рейтинг сайта в поисковых системах, так как они не знают, какую страницу показывать в результатах поиска и как распределять ссылочный вес между ними. Канонический URL-адрес помогает решить эту проблему, указывая поисковым системам, какой URL-адрес является главным или предпочтительным для данной страницы. Таким образом, поисковые системы могут индексировать и показывать только канонический URL-адрес, а не его копии.

Нечего не понятно, сухо.
Почему именно в моделях это написано? Такое чувство что это должно быть в во вьюхах, но кто я такой чтобы спорить

@Ravshan_Battalov, В моделях это написано чтобы получать прямую ссылку на запись, без вызова {% url '' %}Этот метод содержит в себе логику формирования URL-адреса для текущего объекта модели. Вместо того, чтобы генерировать URL-адрес, вы можете просто вызвать этот метод и получить URL-адрес объекта модели.

Очень смущает нарушение инверсии зависимостей. :(

@Anonymous_105352133, ты о чём?