Auto Generated Slugs in Django Admin

2019-09-14 20:44发布

问题:

I have an app that will one day allow front-end crud, which will create the slug with slugify. Right now though, all the object creation is being done in the admin area and I was wondering if there is a way to auto generate slugs while creating and saving an object from within admin?

Here is the method for slugify for the front-end; not sure if its even relevant. Thank you.

def create_slug(instance, new_slug=None):
    slug = slugify(instance.title)
    if new_slug is not None:
        slug = new_slug
    qs = Veteran.objects.filter(slug=slug).order_by('-id')
    exists = qs.exists()
    if exists:
        new_slug = '%s-%s' % (slug, qs.first().id)
        return create_slug(instance, new_slug=new_slug)
    return slug

回答1:

Having just used this on another answer, I have exactly the right code in my clipboard. I do exactly this for one of my models:

from django.utils.text import slugify
class Event(models.Model):

    date = models.DateField()
    location_title = models.TextField()
    location_code = models.TextField(blank=True, null=True)
    picture_url = models.URLField(blank=True, null=True, max_length=250)
    event_url = models.SlugField(unique=True, max_length=250)

    def __str__(self):
        return self.event_url + " " + str(self.date)

    def save(self, *args, **kwargs):
        self.event_url = slugify(self.location_title+str(self.date))
        super(Event, self).save(*args, **kwargs)


回答2:

Above solutions break validation in the Django Admin interface. I suggest:

from django import forms
from django.http.request import QueryDict
from django.utils.text import slugify

from .models import Article


class ArticleForm(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        super(ArticleForm, self).__init__(*args, **kwargs)

        # Ensure that data is a regular Python dictionary so we can
        # modify it later.
        if isinstance(self.data, QueryDict):
            self.data = self.data.copy()

        # We assume here that the slug is only generated once, when
        # saving the object. Since they are used in URLs they should
        # not change when valid.
        if not self.instance.pk and self.data.get('title'):
            self.data['slug'] = slugify(self.data['title'])

    class Meta:
        model = Article
        exclude = []