justinmayer / django-autoslug

AutoSlugField for Django. Supports (but not does not require) unidecode/pytils for transliteration. Old issue tracker is at Bitbucket: https://bitbucket.org/neithere/django-autoslug/issues

Home Page:https://readthedocs.org/projects/django-autoslug/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

AssertionError: slug is defined before trying to ensure uniqueness

illagrenan opened this issue · comments

I have the exact same issue as described on Bitbucket: https://bitbucket.org/neithere/django-autoslug/issues/45/slug-is-defined-before-trying-to-ensure.

Here is my code (Django 1.10.3 and Python 3.5.2):

class Query(models.Model):
    text = models.CharField(max_length=512, unique=True, db_index=True)
    slug = AutoSlugField(populate_from='text', db_index=True, unique=True, always_update=True)
    # ...

The problem occurs when I try to save Query model with unsluggable data in the text field:

>>> Query.objects.get_or_create(text="???????")
***\lib\site-packages\autoslug\fields.py in pre_save(self, instance, add)
    270
    271         if not self.blank:
--> 272             assert slug, 'slug is defined before trying to ensure uniqueness'
    273
    274         if slug:

AssertionError: slug is defined before trying to ensure uniqueness

The source of the problem is following code in autoslug/utils.py (Note: I have unidecode installed):

# ...

# Use Django's default method over decoded string
    def slugify(value):
        return django_slugify(unidecode(value))

# ...

Django slugify function fails to create slug from text ??????? and autoslug fails on AssertionError.

I don't know how should autoslug behave in these situations but it would be great to provide nicer error (e.g. raise ValueError("Sorry but it is not possible to create slug from...")).

To @egregors: Try to install unidecode: pip install unidecode. Standard slugify function in Django doesn't work on all non-ascii data:

In [1]: from django.template.defaultfilters import slugify

In [2]: slugify('Привет!')
Out[2]: ''

vs:

In [4]: from unidecode import unidecode

In [5]: unidecode('Привет!')
Out[5]: 'Privet!'

Autoslug will use unidecode automatically, see this code: https://github.com/neithere/django-autoslug/blob/master/autoslug/utils.py#L19-L20.

Is this related to #18 and does this PR fix the issue?

Thanks for your message. I'll try it tomorrow and let you know.

I can confirm that the #18 fixes this bug. 👍