Сообщим Django, что нужно предзаполнять поле slug данными, вводимыми в поле title, используя атрибут prepopulated_fields.
Для этого в файле admin.py изменим следующий код:
admin.site.register(Post)
На следующий:
@admin.register(Post)
class PostAdmin(admin.ModelAdmin):
"""
Админ-панель модели записей
"""
prepopulated_fields = {'slug': ('title',)}
Мы добавили параметр prepopulated_fields, который позволяет с помощью встроенного JS обрабатывать заголовок в реальном времени, конвертирует даже кириллицу. Перейдем в админ панель, и попробуем добавить новую статью.
И мы видим, что при добавлении названии статьи, у нас автоматически заполняется поле Slug (URL). Заполним все остальные поля и добавим ее. Теперь попробуем добавить еще одну статью с таким же именем, мы получим ошибку, так как такое Slug уже существует:
Давайте сделаем уникализацию наших слагов, первым делом для обработки кириллицы в поле slug, нам нужно модернизировать функцию slugify(), для этого установим пакет pytils с помощью терминала:
pip install pytils
Pytils это инструменты для работы с русскими строками (транслитерация, числительные словами, русские даты и т.д.)
Теперь создадим папку services в папке apps, а внутри её создадим файл utils.py:
В файл utils.py мы будем добавлять различные полезные функции для нашего проекта, поэтому мы ее отделим от приложения блог. В дальнейшем это будет более удобно для разработки и доработки нашего проекта.
Добавим в apps/services/utils.py следующий код обработки:
from uuid import uuid4
from pytils.translit import slugify
def unique_slugify(instance, slug):
"""
Генератор уникальных SLUG для моделей, в случае существования такого SLUG.
"""
model = instance.__class__
unique_slug = slugify(slug)
while model.objects.filter(slug=unique_slug).exists():
unique_slug = f'{unique_slug}-{uuid4().hex[:8]}'
return unique_slug
Теперь функцию unique_slugify() необходимо добавить в модели Post (Статей).
from apps.services.utils import unique_slugify
class Post(models.Model):
"""
Модель постов для нашего блога
"""
slug = models.SlugField(verbose_name='URL', max_length=255, blank=True)
# Поля модели и метакласс
# Функции str и get_absolute_url
def save(self, *args, **kwargs):
"""
При сохранении генерируем слаг и проверяем на уникальность
"""
self.slug = unique_slugify(self, self.title)
super().save(*args, **kwargs)
Первым делом мы удалим unique=True в поле slug, так как проверку уникальности мы передали функции unique_slugify
Мы импортировали функцию по генерации slug, а также добавили метод save для обработки полей экземпляра. В условии, если нет slug, то мы генерируем slug из заголовка, а если такой slug существует, то мы добавляем символы uuid4.
Выполним миграции:
python manage.py makemigrations
python manage.py migrate
Давайте проверим работу, запустим сервер и перейдем в админ панель. Попробуем создать еще раз запись, у которой совпадает название:
Нажмем кнопку СОХРАНИТЬ, и мы видим что наша запись успешно создалась.
Попробуем перейти в запись и посмотрим её слаг.
Мы видим что наша функция успешно отработала, слаг стал уникальным используя uuid4.