Как в 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={'post_title_slug': self.post_slug})
urls.py:
path('post/<slug:post_title_slug>/', ShowPost, name='show_post'),
views.py:
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)
base.html:
{% for random_thumbnail_one in random_content_one %}
<button type="button" class="btn btn-sm btn-outline-secondary">
<a class="plink" href="{{ random_thumbnail_one.get_absolute_url }}">View</a>
</button>
{% endfor %}
Работает только если title был заполнен английскими буквами. Если русскими то возникает ошибка. К примеру если title = "собака", то ошибка будет такая:
NoReverseMatch at
Reverse for 'show_post' with keyword arguments '{'post_title_slug': 'собака-1672068769'}' not found. 1 pattern(s) tried: ['post/(?P<post_title_slug>[-a-zA-Z0-9_]+)/\\Z']
P.S: С уникальностью slug'ов проблем нет, т.к дополнительно используется модуль time при генерации url'ов
Ответы (2 шт):
Автор решения: Борис Плесцов
→ Ссылка
Библиотека transliterate.
slug = slugify(transliterate (title, 'ru', reversed=True))
Автор решения: Dmitry Websmith
→ Ссылка
pip uninstall slugify
pip install python-slugify
main.py
from slugify import slugify
if __name__ == '__main__':
print(slugify("собака"))
