You are on page 1of 7

KNOWLEDGE FOR THE WORLD HOME INTERESTS SIGN UP SIGN IN

Getting Started With Django Forms Share Favorite Comment

0 COMMENTS

by Dayne (47)
IN THESE INTERESTS

django
Django forms are an excellent way to manage user input in a Django application. Once you learn how 20 SUBSCRIBERS SUBSCRIBE

to wield them, you'll never go back to manually coding a form tag and handling the response. This
python
guide will scratch the surface but get you far enough to begin using and learning the power of
103 SUBSCRIBERS SUBSCRIBE
Django's Form class.

Let's dive in.

1 Why should you use Django forms?


Django forms save time and code. Because of their class based nature, you are able to reuse forms
saving you time and complexity.

Using a mature web framework's form class also enforces more secure code than you write
(probably). For example, Django forms will complain loudly if you do not use CSRF protection,
something that can easily go forgotten if you're manually coding a form.

2 How Do Django forms work?


Django's Form class is the heartbeat of Django's form components. In the same way Django's Model
class describes an object, the Form class describes a form. A Model's fields describe individual
database columns and a Form's fields describe individual form elements.

class ArticleForm(
ArticleForm(forms.
forms.ModelForm)
ModelForm):
forms.
title = forms .CharField
CharField(
()
forms.
desc = forms.TextField
TextField(()

Meta:
class Meta:
model = Article

3 4 basic steps to using Django forms


1. create a form class for your needs (usually in forms.py)
2. instantiate that form class (usually in a view)
3. render that form (usually in a template)
4. instantiate the same form class with POST data (aka bind data to the form)

There are other minor steps which we will cover, but this is the basic framework for using Django
forms.

4 Example #1 - Setting up a basic contact form


Create a form class. This class represents a contact form that takes name, email, and message inputs.
Django chooses an HTML element based on the type of field you specify. You can also override this
choice by passing in a 'widget' argument.

from django import forms

ContactForm(
class ContactForm (forms
forms.
.Form
Form)
):
name = forms.
forms.CharField(
CharField()
forms.
email = forms .EmailField
EmailField(()
forms.
message = forms .CharField
CharField((widget
widget=
=forms
forms.
.Textarea
Textarea))
Create a view

# at the top of the file


from .forms import ContactForm

def contact(
contact(request
request)
):
ContactForm(
contact_form = ContactForm ()
render(
return render(request
request,
, "contact.html"
"contact.html",
, {"form"
"form":
: contact_form
contact_form}
})

Setup a new url

url(
url(r'^contact/?$'
'^contact/?$',
, contact
contact,, name
name=
='contact'
'contact')
)

Create a template

h1>
<h1>Contact
Contact<</h1
h1>
>
<form role=
role="form" action=
action="" method
method=
="post"
"post">>
{% csrf_token %}
{{ form }}
type=
<button type ="submit"
"submit">
>Submit
Submit<
</button
button>
>
form>
</form>

Handle the POST request in the view

if request.
request.method == 'POST':
'POST':
ContactForm(
contact_form = ContactForm(data
data=
=request
request.
.POST
POST)
)

if contact_form.
contact_form.is_valid
is_valid(():
request.
name = request.POST
POST..get
get(
('name'
'name',
, '')
'')
email = request.
request.POST.
POST.get(
get('email',
'email', '')
'')
request.
message = request .POST
POST.
.get
get(
('message'
'message',
, '')
'')
# do some processing with name and email
messages.
messages.success
success((request
request,, 'Your message has been sent!')
sent!')
redirect(
return redirect('contact'
'contact') )
else:
else:
ContactForm(
contact_form = ContactForm ()

5 Example #2 - Setting up a model form to create


objects
Create a model

django.
from django.db import models

Article(
class Article(models
models.
.Model
Model)
):
title = models.
models.CharField(
CharField(max_length=
max_length=1000)
1000)
models.
desc = models.CharField
CharField((max_length
max_length=
=1000
1000)
)

# makemigrations && migrate

Create a form

from django import forms

from .models import Article

ArticleForm(
class ArticleForm(forms
forms.
.ModelForm
ModelForm)):
Meta:
class Meta:
model = Article
'title',
fields = ['title', 'desc'
'desc',
,]

Create a view

# at the top of the file


from .forms import ArticleForm
def article_create(
article_create(request
request)):
ArticleForm(
article_form = ArticleForm ()
render(
return render(request
request,, "article_form.html"
"article_form.html",
, {"form"
"form":
: article_form
article_form}
})

Setup a new url

url(
url(r'^articles/create?$'
'^articles/create?$',
, contact
contact,, name
name=
='article_create'
'article_create')
)

Create a template

h1>
<h1>Article Form<
Form</h1
h1>
>
<form role=
role="form" action
action=
="" method=
method="post"
"post">
>
{% csrf_token %}
form.
{{ form.as_p }}
<button type
type=
="submit"
"submit">
>Submit
Submit<
</button
button>
>
form>
</form>

Update description field widget

class ArticleForm(
ArticleForm(forms.
forms.ModelForm)
ModelForm):
Meta:
class Meta:
model = Article
'title',
fields = ['title', 'desc'
'desc',
,]
widgets = {
'desc':
'desc': forms.
forms.Textarea(
Textarea(attrs=
attrs={'class':
'class': 'desc'}
'desc'}),
}

Handle the POST request in the view

if request.
request.method == 'POST'
'POST':
:
ArticleForm(
article_form = ArticleForm(data
data=
=request
request.
.POST
POST)
)

if article_form.
article_form.is_valid
is_valid(():
article_form.
article = article_form .save
save(
()
redirect(
return redirect('article-detail'
'article-detail',
, pk
pk=
=article
article.
.pk
pk)
)
else:
else:
article_form = ArticleForm(
ArticleForm()

6 Example #3 - Setting up a model form to update


objects
Create a view

def article_edit(
article_edit(request
request,
, pk
pk)
):
try:
try:
Article.
article = Article .objects
objects.
.get
get(
(pk
pk=
=pk
pk)
)
Article.
except Article .DoesNotExist
DoesNotExist::
redirect(
return redirect('article-create'
'article-create') )

ArticleForm(
article_form = ArticleForm(instance
instance==article
article)
)

render(
return render(request
request,
, "article_form.html"
"article_form.html",
, {"form"
"form":
: article_form
article_form}
})

Setup a new url

url(
url(r'^articles/(?P<pk>\d+)/edit?$'
'^articles/(?P<pk>\d+)/edit?$',
, contact
contact,, name
name=
='article-edit'
'article-edit')
)

Handle the POST request in the view

if request.
request.method == 'POST'
'POST':
:
ArticleForm(
article_form = ArticleForm(instance
instance==article
article,
, data
data=
=request
request.
.POST
POST)
)

article_form.
if article_form.is_valid
is_valid(():
article_form.
article = article_form.save
save(
()
redirect(
return redirect('article-detail'
'article-detail',
, pk
pk=
=article
article.
.pk
pk)
)
else:
else:
ArticleForm(
article_form = ArticleForm(instance
instance==article
article)
)

7 Example #4 - Adding custom validation to a form


Custom Clean Method

def clean_title(
clean_title(self)
self):
self.
title = self .cleaned_data
cleaned_data.
.get
get(
('title'
'title',
, None
None)
)

if 'django' not in title


title.
.lower
lower(
():
forms.
raise forms.ValidationError
ValidationError(("You forgot to talk about Django!")
Django!")

return title

8 Odds and ends


Different ways to display a form in HTML

Default or .as_table()

article_form = ArticleForm(
ArticleForm()
print(
print(article_form
article_form)
) # or print(article_form.as_table())

# results

<tr>
tr>
th>
<th><label for
for=
="id_title"
"id_title">
>Title
Title:
:</label
label>
></th
th>
>
td>
<td><input id
id=
="id_title" maxlength
maxlength=
="1000" name
name=
="title" type
type=
="text" /></td
td>
>
tr>
</tr>
tr>
<tr>
<th>
th><label for=
for="id_desc">
"id_desc">Desc:
Desc:</label>
label></th>
th><td>
td>
class=
<textarea class ="desc" cols
cols=
="40" id
id=
="id_desc" maxlength
maxlength=
="1000" name
name=
="desc" rows
rows=
="10"
"10">
></textarea
textarea>
><
tr>
</tr>

.as_p()

ArticleForm(
article_form = ArticleForm ()
print(
print(article_form
article_form.
.as_p
as_p(
())

#results

<p>
<label for=
for="id_title"
"id_title">>Title
Title:
:</label
label>
>
id=
<input id="id_title" maxlength
maxlength=="1000" name
name=
="title" type
type=
="text" />
</p>
<p>
for=
<label for="id_desc"
"id_desc">
>Desc
Desc::</label
label>
>
class=
<textarea class ="desc" cols
cols=="40" id
id=
="id_desc" maxlength
maxlength=
="1000" name=
name="desc" rows
rows=
="10"
"10">
></textarea
textarea>
>
</p>

article_form.as_ul()

ArticleForm(
article_form = ArticleForm()
print(
print(article_form
article_form.
.as_ul
as_ul(
())

#results

li>
<li>
for=
<label for="id_title"
"id_title">
>Title
Title:
:</label
label>
>
id=
<input id="id_title" maxlength
maxlength=
="1000" name
name=
="title" type
type=
="text" />
li>
</li>
<li>
li>
<label for
for=
="id_desc"
"id_desc">
>Desc
Desc:
:</label
label>
>
class=
<textarea class="desc" cols
cols=
="40" id
id=
="id_desc" maxlength
maxlength=
="1000" name
name=
="desc" rows
rows=
="10"
"10">
></textarea
textarea>
>
li>
</li>

9 Iterating through form object


In Python

ArticleForm(
article_form = ArticleForm ()
article_form:
for field in article_form:
print(
print(field)
field)

# results
id=
<input id="id_title" maxlength
maxlength=
="1000" name
name=
="title" type
type=
="text" />
class=
<textarea class ="desc" cols
cols=
="40" id
id=
="id_desc" maxlength
maxlength=
="1000" name=
name="desc" rows
rows=
="10"
"10">
></textarea
textarea>
>

In Template

{% for field in form %}


class=
<div class="fieldWrapper"
"fieldWrapper">
>
field.
{{ field .errors }}
field.
{{ field .label_tag }}
{{ field }}
field.
{% if field .help_text %}
class=
<p class="help"
"help">
>{{ field.
field.help_text
help_text|
|safe }}</p>
{% endif %}
</div
div>
>
{% endfor %}

10 Conclusion
Pros of Django Forms

1. Huge timesaver and code saver


2. Very powerful
3. Well documented
4. Good community support

Weaknesses

1. There is a lot of configuration


2. You will spend tons of time in the docs at first
3. You will run into trouble trying to customize the display of your form fields (crispy forms helps)
4. Django does nothing with Javascript so for super Javascripty forms, you're on your own

A word about Crispy Forms

• Extremely customizable form output


• Helps keep code DRY
• Sticks to Django conventions so it does not feel like a 3rd party package
• https://github.com/maraujop/django-crispy-forms

Share Favorite Comment

0 COMMENTS

Dayne (47)
Dayne loves hacking things, in both a computer sense and a wielding an
axe sense.
Share this guide!
Email

Related to this guide:

0 0 0 2 0 0

Combine Two Querysets in Why and how we use Django How to validate yaml from the
Django (with different models) howchoo was originally built in PHP and
command line (using Python)
Today, I stumbled upon a use case where I needed Codeigniter, then we switched completely to This guide will show you how to validate yaml on
to have a querysets that had objects from different Django in February of 2015. the command line using Python.
models. Django has a neat "contenttypes
framework" which is a good way to achieve this. tyler View tyler View

Ashley View

People also read:


How to add a Raspberry Pi potentiometer
by Ash in python, pi

How to install and use Python 3 on MacOS


by tyler in python, code, programming

Unit Testing in Python: Tips, Tricks, and Gotchas


by tyler in code, python, programming

How to control a DC motor (or motors) using your Raspberry Pi


by Zach in pi, python

How to use Siri to control anything -- from IFTT to custom programs and devices
by tyler in pi, python, apple

How to add a power button to your Raspberry Pi


by tyler in python, pi

How to format JSON in Vim


by tyler in vim, python

Posted in these interests:

django 5 GUIDES python 37 GUIDES

Python is howchoo's favorite programming


language. We believe python promotes the
most organized an...

20 SUBSCRIBERS SUBSCRIBE Explore 103 SUBSCRIBERS SUBSCRIBE Explore


Discuss this guide:

/django

Follow howchoo! About us


Join howchoo!
Our team
Contact us

©2018 howchoo, llc | Sitemap | Terms of use | Privacy policy | DMCA requests

AN ELITE CAFEMEDIA LIFESTYLE PUBLISHER

You might also like