Write Persian in slug and use it in address bar in django

Question:

I use django and in my models I want to write Persian in slugfield (by using utf-8 or something else) and use the slug in address of page
I write this class for model:

class Category(models.Model):
    name = models.CharField(max_length=20, unique=True)
    slug = models.SlugField(max_length=20, unique=True)
    description = models.CharField(max_length=500)
    is_active = models.BooleanField(default=False)
    meta_description = models.TextField(max_length=160, null=True, blank=True)
    meta_keywords = models.TextField(max_length=255, null=True, blank=True)
    user = models.ForeignKey(settings.AUTH_USER_MODEL)

    def save(self, *args, **kwargs):
        self.slug = slugify(self.name)
        super(Category, self).save(*args, **kwargs)

    def __str__(self):
        return self.name

    def category_posts(self):
        return Post.objects.filter(category=self).count()

But there is nothing in slug column after save and I don’t know what to write in url to show Persian. Can you tell me what should I do?

I use django 1.9 and python 3.6.

Asked By: amir.m ghazanfari

||

Answers:

The docstring for the slugify function is:

Convert to ASCII if ‘allow_unicode’ is False. Convert spaces to hyphens.
Remove characters that aren’t alphanumerics, underscores, or hyphens.
Convert to lowercase. Also strip leading and trailing whitespace.

So you need to set the allow_unicode flag to True to preserve the Persian text.

>>> text = 'سلام عزیزم! عزیزم سلام!'
>>> slugify(text)
''
>>> slugify(text, allow_unicode=True)
'سلام-عزیزم-عزیزم-سلام'
>>> 
Answered By: snakecharmerb

this is better !!

‍‍‍slug = models.SlugField(max_length=20, unique=True, allow_unicode=True)
Answered By: Ali Noori

Here`s an example which you can use for this case:

First install django_extensions with pip, if it is not installed.

from django_extensions.db.fields import AutoSlugField
from django.utils.text import slugify

In model.py before your class add this function:

def my_slugify_function(content):
    return slugify(content, allow_unicode=True)

In your class add this field:

slug = AutoSlugField(populate_from=['name'], unique=True, allow_unicode=True, slugify_function=my_slugify_function)

In url must use this format:

re_path('person_list/(?P<slug>[-w]+)/', views.detail, name='detail')
Answered By: Mahnaz Divargar

I used snakecharmerb and Ali Noori answers. But those did not solve my problem. And get this error:

Reverse for 'system-detail' with keyword arguments '{'slug': 'هفت'}' not found. 1 pattern(s) tried: ['system/(?P<slug>[-a-zA-Z0-9_]+)/\Z']

In urls.py i Change slug to str:

path('<str:slug>/', SystemDetailView.as_view(), name='system-detail'),
Answered By: Darwin
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.