6

Django Unicode Slug how to ?

class NewsModel(models.Model):
    title = models.CharField(max_length = 300)
    slug = models.CharField(max_length = 300)
    content = models.TextField()
    def save(self,*args, **kwargs):
        if self.slug is None:
             self.slug = ???
        super(NewsModel, self).save(*args, **kwargs)

    def get_absolute_url(self):
        return reverse("news_view", kwargs = {"slug" : self.slug, } )
Ankhaa
  • 1,128
  • 2
  • 12
  • 17
  • possible duplicate of [How to make Django slugify work properly with Unicode strings?](http://stackoverflow.com/questions/702337/how-to-make-django-slugify-work-properly-with-unicode-strings) – Burhan Khalid Mar 27 '12 at 09:16
  • That is worked for my Case. http://pypi.python.org/pypi/Unidecode. http://stackoverflow.com/a/4036665/489943. Thanks. You answer here. – Ankhaa Mar 27 '12 at 09:26
  • possible duplicate of [How do I create a slug in Django?](http://stackoverflow.com/questions/837828/how-do-i-create-a-slug-in-django) – Martijn Pieters Oct 18 '14 at 23:01

3 Answers3

6

Django comes with a function for that:

In [11]: from django.template.defaultfilters import slugify
In [13]: slugify(u'ç é YUOIYO  ___ 89098')
Out[13]: u'c-e-yuoiyo-___-89098'

But really your are better off using the prepopulated_fields parameter and a SlugField.

EDIT:

It seems to be a duplicate question, and the answer proposed in the other OP works quite well. First install unidecode, then:

In [2]: import unidecode
In [3]: unidecode.unidecode(u"Сайн уу")
Out[3]: 'Sain uu

You can pass it to slugify after.

If you are looking for slugs of unicode caractèers, you can use mozilla/unicode-slugify

In [1]: import slugify
In [2]: slugify.slugify(u"Сайн уу")
Out[3]: u'\u0441\u0430\u0439\u043d-\u0443\u0443'

Result is http://example.com/news/сайн-уу

guettli
  • 25,042
  • 81
  • 346
  • 663
Bite code
  • 578,959
  • 113
  • 301
  • 329
  • 1
    Very interesting. That is worked. But this is Mongolian unicode characters. wont work slugify(u"Сайн уу") – Ankhaa Mar 27 '12 at 09:09
  • Ok, slugify uses unicodedata.normalize('NFKD', u"Сайн уу").encode('ascii', 'ignore') to normalize the string, but maybe there is no mapping between Mogolian caracters and ascii. So you'll need to create a mapping yourself and use maketrans (http://docs.python.org/library/string.html#string.maketrans) before you pass it to slugify. – Bite code Mar 27 '12 at 09:17
  • I Found better way. https://github.com/mozilla/unicode-slugify/blob/master/slugify/__init__.py that is very simple and not install any module. – Ankhaa Mar 27 '12 at 09:35
  • The mozilla function won't allow you to translate 'й' into a caracter that is suitable for an URL, unless you are aiming for non ASCII URLs. – Bite code Mar 27 '12 at 10:39
  • 'й' is fine. That worked [here](http://mgleuro.com/public/gallery.html/133276227453-%D1%88%D0%B2%D0%B5%D0%B4%D0%B8%D0%B9%D0%BD-%D1%81%D0%B0%D0%B3%D1%81%D0%B0%D0%BD-%D0%B1%D3%A9%D0%BC%D0%B1%D3%A9%D0%B3%D0%B8%D0%B9%D0%BD-%D0%BB%D0%B8%D0%B3%D1%82-%D1%82%D0%BE%D0%B3%D0%BB%D0%BE%D0%B6-%D0%B1%D0%B0%D0%B9%D0%B3%D0%B0%D0%B0-mgl-%D0%B1%D0%B0%D0%B3-1260664) – Ankhaa Mar 27 '12 at 12:35
  • Hence the "unless you are aiming for non ASCII URL " which you didn't mentioned" – Bite code Mar 27 '12 at 13:04
  • First able i try using standart django slugify function. Finally i understand this non ASCII URL is better for me. My customers can read URL in address bar. – Ankhaa Mar 27 '12 at 16:24
  • @Ankhaa >> and not install any module. Seems like need to install `unicode-slugify` – Ivan Borshchov Nov 15 '16 at 12:50
1

Presuming you want to automatically create a slug based on your NewsModel's title, you want to use slugify:

from django.template.defaultfilters import slugify

def save(self,*args, **kwargs):
  if self.slug is None:
    self.slug = slugify(self.title)
  super(NewsModel, self).save(*args, **kwargs)
Dominic Rodger
  • 97,747
  • 36
  • 197
  • 212
0

This is what i am using in my projects. i know this question is for many times ago but i hope my solution help someone. i should mention that there is a good solution for this in https://github.com/mozilla/unicode-slugify but this is what i use:

import re
import unicodedata

try:
    from django.utils.encoding import smart_unicode as smart_text
except ImportError:
    from django.utils.encoding import smart_text

def slugify(value):
    #underscore, tilde and hyphen are alowed in slugs
    value = unicodedata.normalize('NFKC', smart_text(value))
    prog = re.compile(r'[^~\w\s-]', flags=re.UNICODE)
    value = prog.sub('', value).strip().lower()
    return re.sub(r'[-\s]+', '-', value)