Django: Slug in Vietnamese working not correctly
<p>I begin to develop website online store using Django framework. I have faced with problem that I want to change the name in Vietnamese "nhá»¯ng-viÃªn-káº¹o" to "nhung-vien-keo". I have read this article: 
<a href="http://stackoverflow.com/questions/1605041/django-slug-in-vietnamese">Django: Slug in Vietnamese</a></p>

<p>and I do something on model.py like this:</p>

<pre><code># -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models
from django.template.defaultfilters import slugify

class Category(models.Model):
    name = models.CharField(max_length=50)
    slug = models.CharField(max_length=50, unique=True,help_text = 'Unique value for product page URL, created from name.')
    description = models.TextField()
    is_active = models.BooleanField(default=True)
    meta_keywords = models.CharField("Meta Keywords", max_length=255, help_text='Comma-delimited set of SEO keywords for meta tag')
    meta_description = models.CharField("Meta Description", max_length=255,  help_text = 'Content for description meta tag')
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:  
        db_table = 'categories'
        ordering = ['-created_at']
        verbose_name_plural = 'Categories'

    def __unicode__ (self):
        return self.name

    @models.permalink
    def get_absolute_url(self):
        return ('catalog_category', (), { 'category_slug': self.slug })
</code></pre>

<p>But when I type "nhá»¯ng-viÃªn-káº¹o" in the Name field of Admin page, the slug field appear "nhng-vien-ko". I don't know something wrong. 
And when I run a test with:</p>

<pre><code># -*- coding: utf-8 -*-
from __future__ import unicode_literals
vietnamese_map = {
    ord(u'Æ°'): 'u',
    ord(u'Æ¡'): 'o',
    ord(u'Ã¡'): 'a',
    ord(u'n'): 'n',
    ord(u'h'): 'h',
    ord(u'á»¯'): 'u',
    ord(u'n'): 'n',
    ord(u'g'): 'g',
    ord(u'v'): 'v',
    ord(u'i'): 'i',
    ord(u'Ãª'): 'e',
    ord(u'n'): 'n',
    ord(u'k'): 'k',
    ord(u'áº¹'): 'e',
    ord(u'o'): 'o',
}

print unicode("nhá»¯ng-viÃªn-káº¹o").translate(vietnamese_map)
</code></pre>

<p>It work correctly, and return "nhung-vien-keo"</p>

<p>[EDIT]</p>

<p>I have try this on my form.py</p>

<pre><code>class CategoryAdminForm(forms.ModelForm):

    class Meta:
        model = Category
        exclude = ()

    def clean_slug(self):
        slug = self.cleaned_data['slug']
        vietnamese_map = {
            ord(u'Æ°'): 'u',
            ord(u'Æ¡'): 'o',
            ord(u'Ã¡'): 'a',
            ord(u'n'): 'n',
            ord(u'h'): 'h',
            ord(u'á»¯'): 'u',
            ord(u'n'): 'n',
            ord(u'g'): 'g',
            ord(u'v'): 'v',
            ord(u'i'): 'i',
            ord(u'Ãª'): 'e',
            ord(u'n'): 'n',
            ord(u'k'): 'k',
            ord(u'áº¹'): 'e',
            ord(u'o'): 'o',
        }
        slug = slugify(unicode(slug).translate(vietnamese_map))
        return slug
</code></pre>

<p>And in admin.py</p>

<pre><code>class CategoryAdmin(admin.ModelAdmin):

    form = CategoryAdminForm
    # sets up values for how admin site lists categories
    list_display = ('name', 'created_at', 'updated_at',)
    list_display_links = ('name',)
    list_per_page = 20
    ordering = ['name']
    search_fields = ['name', 'description', 'meta_keywords', 'meta_description']
    exclude = ('created_at', 'updated_at',)
    # sets up slug to be generated from category name
    prepopulated_fields = {'slug': ('name',)}

admin.site.register(Category, CategoryAdmin)
</code></pre>

<p>But it still not work!</p>

<pre><code>if not self.slug:
    ...
    self.slug = slugify(unicode(self.slug).translate(vietnamese_map))
</code></pre>

<p>Your logic here is "translate slug only if slug is empty". Firstly, try to remove this condition (because it doesn't make sense). Secondly, try to make this work in forms instead, because at the point of model saving your slug is already processed by <code>slugify</code> function of django. To do this:</p>

<ol>
<li><p>Create ModelForm for your class:    </p>

<pre><code>class SomeModelForm(forms.ModelForm):

    class Meta:
        model = SomeModel
        exclude = ()

    def clean_slug(self):
        slug = self.cleaned_data['slug']
        # Consider adding vietnamese_map here 
        slug = slugify(unicode(slug).translate(vietnamese_map))
        return slug
</code></pre></li>
<li><p>In your admin class: </p>

<pre><code>class YourModelAdmin(admin.ModelAdmin):
    form = SomeModelForm
</code></pre></li>
</ol>

<p>You may need to replace <code>SlugField</code> with regular <code>CharField</code> at the point.</p>

python django slug