The Emma Frost Comic Book Database was my first Django project when I was familiarizing myself with the web framework and the Python programming language.
The models for the comic book database seemed relatively easy, but I came across problems that I didn’t consider, such as prepopulating a slug field from a foreign key. The comic book Title is a foreign key that goes into the Issue model. Selecting a title from a drop-down list should automatically prepopulate the slug field if defined in the admin.py, right? Nope, it comes up blank and will only prepopulate character fields – which is most likely a front-end Javascript issue.
Thanks to Justin Myers, he came up with a simple, bang-your-head-on-the-desk solution for generating slugs from foreign keys that I’d like to share since it is a common question.
Here’s how to do it, given an abbreviated example of my models.py file:
class Title(models.Model): title = models.CharField(max_length=64) slug = models.SlugField() def get_absolute_url(self): return "/titles/%s" % self.slug def __unicode__(self): return self.title class Issue(models.Model): title = models.ForeignKey(Title) number = models.CharField(max_length=20) slug = models.SlugField(blank=True) def __unicode__(self): return u'%s #%s' % (self.title, self.number) # Here is where the code you need starts. def save(self, *args, **kwargs): # Creates the slug, including the foreign key's slug. self.slug = str(self.title.slug) # Calls the parent save() super(Issue, self).save(*args, **kwargs) # Adds the number self.slug = str(self.title.slug) + '-' + str(self.number) # Calls the parent save() again super(Issue, self).save(*args, **kwargs)
So, for example, when you save the Issue model in the Django admin, the slug field generates something like this, comics.emmafrostfiles.com/issues/astonishing-x-men-12 – which, by the way, has one of my favorite variant covers!
I had about 900 issues that needed to be “slugged.” Of course, I didn’t click “save” on each issue 900 times – that would have been too tedious. Login to SSH and save all the objects in the model you need slugged:
>>> for issue in Issue.objects.all():
… issue.save()
I actually ran into a problem that did not throw me an error – but it was a simple fix. Make sure your character length for the slugs are right. You’ll have to go into your database admin to edit the length.
Good luck!
Thank you!