Loading...

Django Model Form Factory Explained

Emilian F. Published on 15 June, 2012

Django forms are great, however, it can be quite tedious to type out a form definition for each one of your models especially if the models share the same fields. For example, if you have a common set of SEO fields (such as meta description, keywords and title) for multiple models (such as categories, products and pages) then you can automatically generate the forms. How? It is not really explained in the Django documentation, but you can use the modelform_factory function.

Let's create a sample model for a an HTML page:

from django.db import models
from django.utils.translation import ugettext_lazy as _

class Page(models.Model):
    """A simple HTML page
    """

    meta_title = models.CharField(_(u"Meta title"), blank=True, max_length=80)
    meta_keywords = models.TextField(_(u"Meta keywords"), blank=True)
    meta_description = models.TextField(_(u"Meta description"), blank=True)

Now that we have a model, let's generate a form for it that displays all of the fields:

from django.forms.models import modelform_factory
PageForm = modelform_factory(Page)

Now let's generate a form that only displays the meta_title and meta_keywords fields:

from django.forms.models import modelform_factory
PageForm = modelform_factory(Page, fields=("meta_title", "meta_keywords"))

We can also exclude certain fields by passing in the exclude parameter:

from django.forms.models import modelform_factory
PageForm = modelform_factory(Page, exclude=("meta_title", "meta_keywords"))

The modelform_factory can be combined with a generic form view to automatically create a form for a model and get it displayed and validated. An elegant example of this can be found in django-lfs which uses a generic view called SEOView to automatically generate the form fields and take care of the validation.

If you have other ways of using the modelform_factory function then please let me know in the comments!

Emilian F. Published on 15 June, 2012