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
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)
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 = []