Version 1 (modified by 18 years ago) ( diff ) | ,
---|
It's common for me to want a unique slug based on a user supplied name of an object. Following the pattern outlined at djang-tips-auto-populated-fields, it's easy to get the field populated without user intervention. However, by setting the slug field in the save() method the field isn't validated and thus unique=True restrictions aren't checked. I wrote the following code to attempt to pick slugs which are unique within a particular model. It's certainly not ideal (it suffers from race condition as well as potential for pounding a database with lots of small queries until it finds a good slug field), but it works for my small/mid-sized apps.
Feel free to suggest improvements to 'wam-djangowiki spam@…' (remove the ' spam' from the address there).
def SlugifyUniquely(value, model, slugfield="slug"): """Returns a slug on a name which is unique within a model's table This code suffers a race condition between when a unique slug is determined and when the object with that slug is saved. It's also not exactly database friendly if there is a high likelyhood of common slugs being attempted. A good usage pattern for this code would be to add a custom save() method to a model with a slug field along the lines of: from django.template.defaultfilters import slugify def save(self): if not self.id: # replace self.name with your prepopulate_from field self.slug = SlugifyUniquely(self.name, self.__class__) super(self.__class__, self).save() Original pattern discussed at http://www.b-list.org/weblog/2006/11/02/django-tips-auto-populated-fields """ suffix = 0 potential = base = slugify(value) while True: if suffix: potential = "-".join([base, str(suffix)]) if not model.objects.filter(**{slugfield: potential}).count(): return potential # we hit a conflicting slug, so bump the suffix & try again suffix += 1