Задать вопрос

Тел: +7 965 3737 888





YAAS (Yet Another Auto Slug)

<p>This is the self-populating AutoSlugField I use.  It's not the <a href="">first such snippet</a>, but (IMO) it works a bit more cleanly.  It numbers duplicate slugs (to avoid IntegrityErrors on a unique slug field) using an "ask-forgiveness-not-permission" model, which avoids extra queries at each save.  And it's simply a custom field, which means adding it to a model is one line.</p>
class MyModel(models.Model):
    name = models.CharField(max_length=50)
    slug = AutoSlugField(populate_from='name')

Вопрос полезен? Да0/Нет0

Ответы (9):

Ответ полезен? Да0/Нет0

MYSQL USERS! -- Mysql reports errors slightly differently, so use code something like this where the IntegrityError gets caught:

(orig_slug in s_e and 'Duplicate entry' in s_e)

Ответ полезен? Да0/Нет0

I can't seem to get this to work on trunk (r9791) with either MySql or Postgresql, can anyone confirm it is working?


Ответ полезен? Да0/Нет0

As of today, I updated the code above to fix another issue. In cases of model inheritance where the superclass has an AutoSlugField, it seems that contribute_to_class is actually called more than once on the subclass, so it needs to be idempotent, otherwise the original save method will be lost and there will be an infinite loop of the new save method calling itself. This is now fixed.

Ответ полезен? Да0/Нет0

@dimitri-gnidash: I can't duplicate the problem you describe. In fact, my test suite covering this code contains a model with an AutoSlugField and an overridden save() method, and the two work together fine. The only potential gotcha is that the AutoSlugField's value won't reflect any change to the populate_from attribute in the overridden save() method; the save() method is called, but the slugification happens first.

Fixing this appears more than a bit difficult, which is why I haven't attempted it yet.

Ответ полезен? Да0/Нет0

There is an infrequent problem with this code. When a method that is added through contribute_to_class is also overridden on the model, the method added through contribute_to_class is not called. I am guessing this is because the overridden method is evaluated later?

Does anyone know of a solution?

Ответ полезен? Да0/Нет0

uandt: Thanks for the feedback. I discovered the IntegrityError issue on MySQL and it's now fixed in the code (by using str(e) instead of e.message).

Good catch on needing to pass args and *kwargs through to _orig_save, that's now fixed as well.

Ответ полезен? Да0/Нет0

Found two problems with this code in the contribute_to_class method :

Ответ полезен? Да0/Нет0

Maybe, but I've had problems with the Javascript slugify not being very reliable. For instance, it breaks if the field is completed by the Firefox auto-completer dropdown. In any case, this snippet plays nicely with the Javascript slugify if you like, as it can be set to not overwrite an existing value for the slug field.

Ответ полезен? Да0/Нет0

Problem is that Python slugify is inferior to JavaScript slugify.