Entries tagged with 'django'

Add Custom Fields to Django Flatpages

I was attempting to build a sort of self-building website, where one could add new pages with custom URLs right from the admin interface. This would allow non-tech users to easily expand their website. After asking a few questions, I got pointed to some nice Django functionality that basically already does this: the Django flatpages app.

I got it up and running pretty painlessly, and it works for simple pages. However, it only has three fields built-in: URL, title, and content. I need a little more control than that- meta description, for example. After bugging plenty of people on the #django IRC channel, I've cobbled together this solution:

models.py

  1. from django.contrib.flatpages.models import FlatPage
  2.  
  3. class FlatPageExtra(models.Model):
  4. flatpage = models.ForeignKey(FlatPage,
  5. edit_inline=models.STACKED,
  6. max_num_in_admin=1,
  7. num_in_admin=1)
  8. description = models.CharField(max_length=255,
  9. core=True)
  10. headline = models.CharField(max_length=255,
  11. core=True)
  12.  
  13. class Admin:
  14. pass

Here we are creating a new model (call it whatever you want). Make a field (also named anything, I chose flatpage) that is a Foreign key to the FlatPage model- don't forget to import! This allows you to associate your custom fields with their respective flatpages. I specified edit_inline=models.STACKED, max_num_in_admin=1, num_in_admin=1 because it pretty much only makes sense to edit your custom fields on the same page as the built-in fields, and there's only going to be one of each (at least in this case). Database enthusiasts would probably also specify unique=True, but I don't care either way. Add whatever other fields you want associated with your flatpages.

Run syncdb, fire up your admin page, and take a look! Note: I included TinyMCE for my content box, but that's better covered in the Django wiki.

In your template, you can grab these values like any other ForeignKey field: {{flatpage.flatpageextra_set.all.0.description}}. Note the .0. because it's actually a collection, even though we know there's always just one item.