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

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

6.6 Добавление функциональности тегирования
2 из 2 шагов пройдено

Добавление функциональности тегирования

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

django-taggit – это приспособленное для использования приложение, которое в первую очередь предлагает модель Tag и менеджер для удобного добавления тегов в любую модель. Исходный код приложения доступен для просмотра на странице https://github.com/jazzband/django-taggit.

Сначала необходимо установить приложение django-taggit с помощью pip, выполнив следующую ниже команду:

pip install django-taggit

 Затем откройте файл settings.py проекта mysite и добавьте taggit в настроечный параметр INSTALLED_APPS, как показано ниже:

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

Откройте файл models.py приложения blog и добавьте предоставляемый приложением django-taggit менеджер TaggableManager в модель Post, используя следующий ниже исходный код:

from taggit.managers import TaggableManager

class Post(models.Model):

    # ...

    tags = TaggableManager()

Менеджер tags позволит добавлять, извлекать и удалять теги из объектов Post.

Приведенная ниже схема показывает модели данных, определенные в приложении django-taggit для создания тегов и хранения схожих тегированных объектов:

Модель Tag используется для хранения тегов. Она содержит поля name и slug.

Модель TaggedItem используется для хранения схожих тегированных объектов. В ней есть поле ForeignKey для схожего объекта Tag.

Она содержит внешний ключ ForeignKey к объекту ContentType и целочисленное поле IntegerField для хранения соответствующего id тегированного объекта.

Поля content_type и object_id в сочетании образуют обобщенное отношение с любой моделью в проекте.

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

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

python manage.py makemigrations blog

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

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

python manage.py migrate

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

Теперь база данных синхронизирована с моделями taggit, и можно начать использовать функциональности приложения django-taggit.

Давайте сейчас проинспектируем способы применения менеджера tags. Откройте оболочку Django, выполнив следующую ниже команду в командной строке системной оболочки:

python manage.py shell

Выполните следующий ниже исходный код, чтобы получить один из постов (пост с ID = 1):

from blog.models import Post
post = Post.objects.get(id=1)

Затем добавьте в него несколько тегов и извлеките его теги, чтобы проверить успешность их добавления:

post.tags.add('music', 'jazz', 'django')

post.tags.all()
<QuerySet [<Tag: jazz>, <Tag: music>, <Tag: django>]>

Наконец, удалите тег и еще раз проверьте список тегов:

post.tags.remove('django')
post.tags.all()
<QuerySet [<Tag: jazz>, <Tag: music>]>

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

Следующей ниже командой запустите сервер разработки и пройдите по URL-адресу http://127.0.0.1:8000/admin/taggit/tag/ в своем браузере. Вы увидите страницу администрирования со списком объектов Tag приложения taggit:

Кликните по тегу jazz. Вы увидите следующее.

Пройдите по URL-адресу http://127.0.0.1:8000/admin/blog/post/1/change/, чтобы отредактировать пост с ID = 1.

Вы увидите, что теперь в посты вставлено новое поле Tags, как показано ниже, в котором можно легко редактировать теги:

В следующем шаге мы отредактируем свои посты в блоге, чтобы отобразить теги.


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

Возможно я что-то пропустила в предыдущих лекциях, но хочу добавить, что для переключения между админкой и сайтом приложения,  в blog/admin.py можно установить значение admin.site.site_url = '/blog' . Тогда возврат на сайт из админки можно через View site в титульной строке, это удобно. Вдруг кто не знает)

Получается мы неявно добавили новую связь Post с классом TaggableManager, то бишь появилось какое-то скрытое поле, через которое мы можешь добавлять к конкретному посту теги и извлекать теги этого поста?

@Шамбер_Егор, мы добавили новый менеджер TaggableManager, он осуществляет поиск постов с определёнными тегами. В модели Tag хранятся теги, а через модель TaggedItem осуществляется связь тега с тегированными постами.

Изменен Дмитрий Селезнев

@Дмитрий_Селезнев, получается, что эти модели из  приложения taggit, понял

@Шамбер_Егор, да.

@Шамбер_Егор, только вот интересно как формируется slug у тега, ибо мы далее используем это в представлении

@Шамбер_Егор, имя тега преобразуется в слаг при добавлении тега:

    def save(self, *args, **kwargs):
        if self._state.adding and not self.slug:
            self.slug = self.slugify(self.name)

https://github.com/jazzband/django-taggit/blob/675e80508d4fd9afb22b93de55080b1ac2b5c302/taggit/models.py#L41C1-L43C48

А почему django не удалился из админки, хотя метод all его больше не возвращает?

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

@Илья_Перминов, с тегами, да, 

@Дмитрий_Чекмасов, они автоматически создаются при добавлении тега к посту, но автоматически не удаляются, если не принадлежат ни одному посту.

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