12. Как использовать поле slug в django для большей читабельности?¶
Slug — это часть URL, которая идентифицирует конкретную страницу на сайте в форме, доступной для чтения пользователями. Для того чтобы это работало, django предлагает нам slugfield. Оно может быть реализовано следующим образом. У нас уже есть модель Article , мы добавим к ней slugfield, чтобы сделать ее читабельной для пользователей.:
from django.utils.text import slugify class Article(models.Model): headline = models.CharField(max_length=100) . . . slug = models.SlugField(unique=True) def save(self, *args, **kwargs): self.slug = slugify(self.headline) super(Article, self).save(*args, **kwargs) . . . >>> u1 = User.objects.get(id=1) >>> from datetime import date >>> a1 = Article.objects.create(headline="todays market report", pub_date=date(2018, 3, 6), reporter=u1) >>> a1.save() // slug here is auto-generated, we haven't created it in the above create method. >>> a1.slug 'todays-market-report'
Слизь полезна, потому что:
он дружелюбен к человеку (например, /blog/ вместо /1/).
хорошим SEO является создание последовательности в заголовке, рубрике и URL.
Как в Django генерировать slug url
Есть задача генерировать slug (при создании поста с помощью формы на сайте) в зависимости от title поста. К примеру:
title = "собака"
url = "127.0.0.1:8000/sobaka"
Пытался использовать функцию slugify : models.py:
def gen_slug(string): finally_slug = slugify(string, allow_unicode=True) return finally_slug + '-' + str(int(time())) class Post(models.Model): post_title = models.CharField(max_length=250, verbose_name='Заголовок') post_slug = models.SlugField(max_length=250, unique=True, verbose_name='URL', null=True, blank=True) def save(self, *args, **kwargs): self.post_slug = gen_slug(self.post_title) super().save(*args, **kwargs) def get_absolute_url(self): return reverse('show_post', kwargs=)
path('post//', ShowPost, name='show_post'),
def homepage(request): random_content_one = Post.objects.order_by("?")[:30] context = < 'random_content_one': random_content_one, >return render(request, 'sitelogic/base.html', context=context) def ShowPost(request, post_title_slug): post = get_object_or_404(Post, post_slug=post_title_slug) context = < 'post': post, 'title': post.post_title, >return render(request, 'sitelogic/showpost.html', context=context)
Работает только если title был заполнен английскими буквами. Если русскими то возникает ошибка. К примеру если title = «собака» , то ошибка будет такая:
NoReverseMatch at Reverse for 'show_post' with keyword arguments '' not found. 1 pattern(s) tried: ['post/(?P[-a-zA-Z0-9_]+)/\\Z']
P.S: С уникальностью slug’ов проблем нет, т.к дополнительно используется модуль time при генерации url’ов
Добавляем слаги (slug) к URL-адресам
На этом занятии мы сделаем отображение отдельных статей по их слагу (slug). Если кто не знает, то slug – это уникальный фрагмент URL-адреса, ассоциированный с конкретной записью и, обычно, состоит из набора маленьких латинских букв, цифр, символов подчеркивания и дефиса. Например, статья «Арифметические операции» на сайте https://proproprogs.ru доступна по следующему адресу:

Здесь slug – это последние символы, по которым и выбирается данная страница из БД. Использование слагов – рекомендуемая практика в веб-программировании. Такие страницы лучше ранжируются поисковыми системами и понятнее конечному пользователю.
Давайте вначале сделаем отображение статей по их идентификатору, а затем, заменим адрес на слаг. У нас уже есть функция-заглушка show_post() в файле women/views.py. Мы ее перепишем, следующим образом:
def show_post(request, post_id): post = get_object_or_404(Women, pk=post_id) context = { 'post': post, 'menu': menu, 'title': post.title, 'cat_selected': 1, } return render(request, 'women/post.html', context=context)
Здесь функция get_object_or_404 выбирает одну запись из таблицы Women, которая имеет идентификатор, равный post_id, либо генерирует исключение 404, если запись не была найдена. Это довольно частая операция, когда нужно найти какую-либо отдельную запись, а в противном случае, перенаправить пользователя на заготовленную страницу 404. Поэтому в Django для таких случаев заготовлена специальная функция.
Далее, формируется словарь из параметров шаблона и отображается страница на основе шаблона post.html. У нас пока нет такого файла, добавим его со следующим содержимым:
{% extends 'women/base.html' %} {% block content %} h1>{{post.title}}/h1> {% if post.photo %} p>img class="img-article-left" src=">">/p> {% endif %} {post.content} {% endblock %}
Здесь все достаточно очевидно. Вначале отображаем заголовок h1, затем, фотографию статьи, если она есть, ну и потом уже содержимое самой статьи.
Если теперь перейти по ссылке, то увидим полноценную статью. Если же указать неверный адрес, то получим исключение 404. Повторю еще раз, исключения в таком развернутом виде отображаются только в режиме отладки сайта. При эксплуатации с константой DEBUG = False вместо исключения отображается заготовленная страница 404.
Добавление слага
Следующим шагом сделаем отображение статей по их слагу. Но откуда нам его взять? Для этого в модели Women необходимо прописать еще одно поле, которое так и назовем – slug:
class Women(models.Model): title = models.CharField(max_length=255, verbose_name="Заголовок") slug = models.SlugField(max_length=255, unique=True, db_index=True, verbose_name="URL") .
Я его определил после поля title, указал уникальным, индексируемым и имя URL, отображаемое в админке. Однако, если сейчас попытаться создать миграцию для внесения этих изменений в структуру таблицы women:
python manage.py makemigrations
то увидим предупреждение, что поле не может быть пустым (так как у нас есть записи в таблице). Чтобы таблицы были сформированы как надо, я решил создать БД заново. Поэтому сразу добавил такое же поле в модели Category:
class Category(models.Model): name = models.CharField(max_length=100, db_index=True, verbose_name="Категория") slug = models.SlugField(max_length=255, unique=True, db_index=True, verbose_name="URL") .
Удалим все файлы миграций, прежний файл БД и выполним команду
python manage.py makemigrations
для создания первой мигации. Затем, с помощью команды:
python manage.py migrate
сформируем таблицы с новыми структурами. Этот пример хорошо показывает, как важно заранее продумывать структуры таблиц для сайта. Осталось восстановить записи в БД. Для этого я заново создам суперпользователя для админки:
python manage.py createsuperuser
с именем root, почтой root@coolsite.ru и паролем 1234. Запускаем веб-сервер и заходим в админ-панель.
Для начала добавим категории. Здесь нам предлагается ввести ее название и слаг (URL). Конечно, можно заполнить оба поля вручную, например, «Актрисы» и «actrisi». Но, так как слаг, обычно, повторяет заголовок, только записанный латиницей, то фреймворк Django позволяет этот процесс автоматизировать. Давайте откроем файл women/admin.py и для модели Category в классе CategoryAdmin добавим атрибут:
prepopulated_fields = {"slug": ("name", )}
Это специальное свойство, которое указывает фреймворку автоматически заполнять поле slug по данным поля name.
Возвращаемся в админку, обновляем страницу и, смотрите, при вводе строки в поле name, автоматически формируется поле slug. Это очень здорово и значительно облегчает нашу работу. Теперь можно совершенно спокойно добавить две рубрики «Актрисы» и «Певицы».
Далее, прежде чем добавлять статьи, сделаем такую же связку по слагу для модели Women в классе WomenAdmin:
prepopulated_fields = {"slug": ("title",)}
только здесь мы указываем поле title. Возвращаемся в админ-панель и на вкладке добавления женщин введем информацию по актрисам:
Анджелина Джоли, Дженнифер Лоуренс, Джулия Робертс, Марго Робби, Ума Турман
А также по певицам:
Ариана Гранде, Бейонсе, Кэтти Перри, Рианна, Шакира
Отлично, база данных готова и теперь можно сделать отображение статей по слагу. Для этого откроем файл women/urls.py и в списке urlpatterns изменим маршрут для постов на следующий:
path('post//', show_post, name='post'),
Затем, в файле women/views.py немного поменяем функцию представления show_post:
def show_post(request, post_slug): post = get_object_or_404(Women, slug=post_slug) .
И в модели Women (в файле women/models.py) будем формировать URL-адрес по параметру slug:
class Women(models.Model): . def get_absolute_url(self): return reverse('post', kwargs={'post_slug': self.slug}) .
Все, обновляем главную страницу сайта и видим, что теперь посты доступны по слагу, а не идентификатору. Этот пример показывает как в Django легко и просто можно менять URL-адреса и вместо id использовать другие поля, в частности, слаг. При этом, мы не производили совершенно никаких изменений в шаблонах, благодаря использованию метода get_absolute_url() в модели Women. Кроме того, Django автоматически защищает такие адреса от SQL-инъекций, когда злоумышленник пытается выполнить SQL-запрос, прописывая его в адресной строке браузера. Благодаря всем этим мелочам, которые берет на себя фреймворк, даже начинающий веб-мастер может конструировать вполне безопасные сайты с богатым функционалом.
Аналогичную операцию использования слагов можно сделать и для отображения рубрик. Предлагаю вам выполнить это самостоятельно для закрепления материала.
Видео по теме

#1. Django — что это такое, порядок установки

#2. Модель MTV. Маршрутизация. Функции представления

#3. Маршрутизация, обработка исключений запросов, перенаправления

#4. Определение моделей. Миграции: создание и выполнение

#5. CRUD — основы ORM по работе с моделями

#6. Шаблоны (templates). Начало

#7. Подключение статических файлов. Фильтры шаблонов

#8. Формирование URL-адресов в шаблонах

#9. Создание связей между моделями через класс ForeignKey

#10. Начинаем работу с админ-панелью

#11. Пользовательские теги шаблонов

#12. Добавляем слаги (slug) к URL-адресам

#13. Использование форм, не связанных с моделями

#14. Формы, связанные с моделями. Пользовательские валидаторы

#15. Классы представлений: ListView, DetailView, CreateView

#16. Основы ORM Django за час

#17. Mixins — убираем дублирование кода

#18. Постраничная навигация (пагинация)

#19. Регистрация пользователей на сайте

#20. Делаем авторизацию пользователей на сайте

#21. Оптимизация сайта с Django Debug Toolbar

#22. Включаем кэширование данных

#23. Использование капчи captcha

#24. Тонкая настройка админ панели

#25. Начинаем развертывание Django-сайта на хостинге

#26. Завершаем развертывание Django-сайта на хостинге
© 2024 Частичное или полное копирование информации с данного сайта для распространения на других ресурсах, в том числе и бумажных, строго запрещено. Все тексты и изображения являются собственностью сайта
Как сделать slug в django
![]()
Обработка кириллицы в Django SlugField (ЧПУ)
27 января 2023
Оценки статьи
Еще никто не оценил статью
В этой статье мы рассмотрим два способа преобразования кириллицы в поле slugField в Django 4.1 для создания ЧПУ — человекопонятного урл.
Встроенная функция slugify() в Django не поддерживает обработку кириллицы, она работает только с латиницей. Чтобы это исправить, существует два способа.
Если вы хотите выразить благодарность автору сайта, статей и курса по Django, вы можете сделать это по ссылке ниже:
Первый способ — долгий. Модернизация функции slugify().
Внутри нашего приложения, например приложения blog, создадим файл utils.py, в котором добавим следующий фрагмент кода:
blog/utils.py
from django.template.defaultfilters import slugify as django_slugify alphabet = 'а': 'a', 'б': 'b', 'в': 'v', 'г': 'g', 'д': 'd', 'е': 'e', 'ё': 'yo', 'ж': 'zh', 'з': 'z', 'и': 'i', 'й': 'j', 'к': 'k', 'л': 'l', 'м': 'm', 'н': 'n', 'о': 'o', 'п': 'p', 'р': 'r', 'с': 's', 'т': 't', 'у': 'u', 'ф': 'f', 'х': 'kh', 'ц': 'ts', 'ч': 'ch', 'ш': 'sh', 'щ': 'shch', 'ы': 'i', 'э': 'e', 'ю': 'yu', 'я': 'ya'> def slugify(s): return django_slugify(''.join(alphabet.get(w, w) for w in s.lower()))
Теперь в нужной модели мы можем использовать модернизированную функцию, например в модели Article (Статья).
blog/models.py
from django.db import models from .utils import slugify class Article(models.Model): title = models.CharField(verbose_name='Заголовок', max_length=255) slug = models.CharField(verbose_name='URL', max_length=255, blank=True, unique=True) # Дугие поля модели. class Meta: ordering = ['title'] # Другие методы. def save(self, *args, **kwargs): """ Метод сохранения экземпляра """ if not self.slug: self.slug = slugify(self.title) return super().save(*args, **kwargs)
С помощью этого метода мы модернизировали встроенную функцию slugify для обработки кириллицы.
Второй способ — быстрый. Установка пакета pytils.
В этом методе мы должны установить дополнительный пакет pytils с помощью команды в терминале: pip install pytils
Результат выполнения:
(venv) PS C:\Users\Razilator\Desktop\Proghunter> pip install pytils Collecting pytils Using cached pytils-0.4.1-py3-none-any.whl Installing collected packages: pytils Successfully installed pytils-0.4.1
Как использовать?
Если в первом примере мы создавали дополнительный файл в нашем приложении blog, то в этом нам просто необходимо импортировать функцию slugify() из установленного пакета pytils.
blog/models.py
from django.db import models from pytils.translit import slugify class Article(models.Model): title = models.CharField(verbose_name='Заголовок', max_length=255) slug = models.CharField(verbose_name='URL', max_length=255, blank=True, unique=True) # Дугие поля модели. class Meta: ordering = ['title'] # Другие методы. def save(self, *args, **kwargs): """ Метод сохранения экземпляра """ if not self.slug: self.slug = slugify(self.title) return super().save(*args, **kwargs)
Вы можете использовать для себя один из этих способов.