Auto Generate Forms with Django's ModelForm
In this short article, we’ll analyze a better way (in some cases) to create forms for your Django models.
If you’ve ever worked with Django forms, then you know that there is a lot of repetitive code involved in the process of writing a form to create your model. Take, for instance, the following model, which represents a physical server (somewhere):
from django.db import models
class Server(models.Model):
"""This class represents a physical server."""
hostname = models.CharField('Server Name',
help_text = 'Hostname of the server.',
max_length = 50
)
ip = models.IPAddressField('Server IP Address',
help_text = 'Public IP of the server.',
unique = True
)
disk_space = models.IntegerField('Disk Space on Server',
help_text = 'Total disk space in MB.'
)
ram = models.IntegerField('RAM on Server',
help_text = 'Total RAM in MB.'
)
cpu = models.IntegerField('Processing Power',
help_text = 'Total Processing Power in MHz.'
)
def __unicode__(self):
"""Make the model human readable."""
return self.hostname
Our Server
model contains several attributes which define a Server
object.
If you want to create a Server
object, you can generate a form class which
can be used to create a new Server
model and store it in the database. This
isn’t very difficult, but is a bit repetitive. Here’s how you would generate a
form to create a new Server
model using Django’s forms:
from django import forms
class CreateServerForm(forms.Form):
"""Create a new Server model."""
hostname = forms.CharField(
label = 'Server Name',
max_length = 50,
required = False
)
ip = forms.IPAddressField )
label = 'Public IP',
required = False
)
disk_space = forms.IntegerField(
label = 'Disk Space in MB',
required = False
)
ram = forms.IntegerField(
label = 'RAM in MB',
required = False
)
cpu = forms.IntegerField(
label = 'CPU in MHz',
required = False
)
As you can see, there’s a lot of repetitive code in there. This is great when you need maximum control of your forms, but is overkill if you’re just trying to build a simple view to create an instance of your model class.
What if there was a way to auto-generate a form class without re-writing all of
that code? Well, there is! Django’s ModelForm
class allows you to create a
very simple ModelForm
without ever touching form code.
Here’s our models.py
code re-written using ModelForm
:
from django.db import models
from django.forms import ModelForm
class Server(models.Model):
"""This class represents a physical server."""
hostname = models.CharField('Server Name',
help_text = 'Hostname of the server.',
max_length = 50
)
ip = models.IPAddressField('Server IP Address',
help_text = 'Public IP of the server.',
unique = True
)
disk_space = models.IntegerField('Disk Space on Server',
help_text = 'Total disk space in MB.'
)
ram = models.IntegerField('RAM on Server',
help_text = 'Total RAM in MB.'
)
cpu = models.IntegerField('Processing Power',
help_text = 'Total Processing Power in MHz.'
)
def __unicode__(self):
"""Make the model human readable."""
return self.hostname
class ServerForm(ModelForm):
"""Auto generated form to create Server models."""
class Meta:
model = Server
Look how much simpler that is! Instead of writing a forms.py
file, and
manually creating a form, we just use ModelForm
to specify a model class that
Django should magically create a form from.
Lastly, let’s see how we can use this new ModelForm
class in an actual view.
It’s easy, I promise:
from myapp.models import Server
from myapp.models import ServerForm
from django.template import RequestContext
from django.shortcuts import render_to_response
def create_server(request):
"""Create a new Server model."""
if request.method == 'POST':
form = ServerForm(request.POST)
if form.is_valid():
# Create a new Server object.
form.save()
else:
form = ServerForm()
variables = RequestContext(request, {
'form': form
})
return render_to_response('path/to/template/create.html', variables)
See how easy that is? In only a few lines, we were able to auto-generate a
form from our model class, and then write a simple view which creates a new
Server
model by using the auto-generated form.
If you’re interested in Django’s ModelForm
, read the
official documentation, it will answer all of your more in-depth questions.
PS: If you read this far, you might want to follow me on Bluesky or GitHub and subscribe via RSS or email below (I'll email you new articles when I publish them).