#12651: AutoSlugField, that can recreate unique slugs during saving.
-------------------------------------+-------------------------------------
     Reporter:  Ciantic              |                    Owner:  nobody
         Type:  New feature          |                   Status:  new
    Component:  Database layer       |                  Version:
  (models, ORM)                      |
     Severity:  Normal               |               Resolution:
     Keywords:                       |             Triage Stage:  Accepted
    Has patch:  1                    |      Needs documentation:  1
  Needs tests:  1                    |  Patch needs improvement:  1
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+-------------------------------------

Comment (by fmalina):

 Just to revive this ticket. Here's an example implementation I find quite
 acceptable in user code:

 {{{#!python
 class Article(models.Model):
     title = models.CharField(max_length=128)
     slug = models.SlugField(max_length=130)
     # ...

     def save(self, *args, **kwargs):
         if not len(self.slug.strip()):
             self.slug = slugify(self.title)

         _slug = self.slug
         _count = 1

         while True:
             try:
                 Article.objects.all().exclude(pk=self.pk).get(slug=_slug)
             except MultipleObjectsReturned:
                 pass
             except ObjectDoesNotExist:
                 break
             _slug = "%s-%s" % (self.slug, _count)
             _count += 1

         self.slug = _slug

         super(Article, self).save(*args, **kwargs)
 }}}

 I've also used a regex based alternative implementation:

 {{{#!python
 import re

 class Article(models.Model):
 ...
     def get_slug(self):
          return '%s-%s' % (slugify(self.this), slugify(self.that))

     def check_slug(self, slug):
         # ensure uniqueness
         while(Article.objects.filter(slug__iexact=slug).count()):  # if
 not unique
             suff = re.search("\d+$", slug)  # get the current number
 suffix if present
             suff = suff and suff.group() or 0
             next = str(int(suff) +1)  # increment it & turn to string for
 re.sub
             slug = re.sub("(\d+)?$", next, slug)  # replace with higher
 suffix, retry
         return slug

     def save(self, *args, **kwargs):
         #...
         slug = self.get_slug()
         if not self.pk or (self.pk and not slug in self.slug):
             self.slug = self.check_slug(slug)
         super( ...
 }}}


 Could this be implemented by adding a pre_save method to the SlugField?
 
https://github.com/django/django/blob/master/django/db/models/fields/__init__.py#L2073

 Maybe call it add_auto_increment=True.

 Any ideas on how this could actually look in the core, as opposed to just
 user code?

--
Ticket URL: <https://code.djangoproject.com/ticket/12651#comment:14>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/065.02e0d9e46776a048402546b675b93454%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to