Desead
@Desead

Как автоматически сформировать slug с русского слова?

есть простая модель:
class ModelZavet(models.Model):
    mz_name = models.CharField('Название для сайта', max_length=200)
    mz_slug = models.SlugField('URL', max_length=70, db_index=True)
    mz_num = models.PositiveSmallIntegerField('Порядок', default=1)
    mz_descriptions = models.TextField('Описание', blank=True)


в admin.py соответственно прописано:
prepopulated_fields = {'mz_slug': ('mz_name',)}

всё отлично работает, slug автоматически создаётся. Без нареканий.
Но тут возникает мысль, что надо бы уметь создавать записи в бд не только через админку, но и через shell. В связи с этим возникает вопрос - а как тогда будет создаваться slug? ведь он должен создаваться автоматически

в модель добавляется такой код:
def save(self, *args, **kwargs):
        if not self.id:
            self.mz_slug = slugify(self.mz_name)
        super(ModelZavet, self).save(*args, **kwargs)

и всё работает. Создаю новую запись через shell, slug при это не задаю, далее вызываю метод save и вижу что в бд есть новая запись и там автоматически созданный slug.
Но, если поле mz_name, с которого создаётся slug написано по русски, то slug не создаётся. Соответственно всё крашится т.к запись становиться не уникальной и прочий ворох проблем. Почему такое только с русским наименованием, что мне исправить?
  • Вопрос задан
  • 3781 просмотр
Пригласить эксперта
Ответы на вопрос 2
netpastor
@netpastor
Python developer
Ответ написан
Комментировать
@VictorSeverlock
from autoslug import AutoSlugField # AutoSlugField нужно дополнительно установить (pip install django-autoslug) - добавляет поля slug
from uuslug import uuslug # нужно дополнительно установить(pip install django-uuslug) - переводит URL-адреса на латиницу

class ModelZavet(models.Model):
...
mz_slug = AutoSlugField('URL', max_length=70, db_index=True, unique=True, populate_form=lambda instance: instance.mz_name, slugify=lambda value: value.replace(' ', '-'))
...

def save(self, *args, **kwargs):
self.mz_slug = uuslug(self.mz_slug, instance=self)
super(ModelZavet, self).save(*args, **kwargs)

# populate_form -> берёт заголовок названия
# slugify=lambda value: value.replace(' ', '-') -> заменяет пробелы на тире

! Для того чтобы не возникло проблем при выполнении миграции -> заменить lambda-функции обычными функциями и написать их перед моделью

def instance_ mz_slug(instance):
return instance.mz_name

def slugify_value(value):
return value.replace(' ', '-')

#должно получится так:
class ModelZavet(models.Model):
...
mz_slug = AutoSlugField('URL', max_length=70, db_index=True, unique=True, verbose_name='URLs',
populate_from= instance_ mz_slug, slugify=slugify_value)
...

! Если в admin.py указано
prepopulated_fields = {'mz_slug': ('mz_name',)} -> нужно удалить или закомментировать

! Больше нигде ничего указывать не надо
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы