shabda
Comments
Reactions

Doing things with Django forms

By : Shabda Raaj

Forms are one of the best features of Django. (After models, admin, url routing etc :) ). Here is a quick tutorial describing how to do things with Django forms.

  1. Basic form

Prob. You want to show a form, validate it and display it.

Ans. Create a simple form.

class UserForm(forms.Form):
    username = forms.CharField()
    joined_on = forms.DateField()

This wil take care that the form is displayed with two text field, and a value for them are filled in, and the second field has correct formatting for a date.

2.

Prob. Create a form which has values populated depending upon a runtime value, eg you might want to show only the values corresponding to the current subdomain.

Ans. Create a form with an custom __init__.

class UserForm(forms.Form):
    username = forms.CharField()
    plan = forms.ModelChoiceField(queryset = Plan.objects.none())

    def __init__(self, subdomain, *args, **kwargs):
        self.default_username = default_username
        super(UserForm, self).__init__(*args, **kwargs)
        self.fields['plan'].queryset = Plan.objects.filter(subdomain = subdomain)

Here in the __init__ we are overriding the default queryset on field plan. Any of the attributes can similarly be overridden.

However the self.fields is populated only after super(UserForm, self).__init__(*args, **kwargs) is called.

3.

Prob. The same form is used in multiple views, and handles the cleaned_data similarly.

Ans. Create a form with a custom .save()

class UserForm(forms.Form):
    username = forms.CharField()

    def save(self):
        data = self.cleaned_data
        user = User.objects.create(username = data['username'])
        #create a profile
        UserProfile.objects.create(user = user, ...some more data...)

You could have called this method anything, but this is generally called save, to maintain similarity with ModelForm

4.

Prob. You need to create a form with fields which have custom validations.

Ans. Create a form with custom clean_fieldname

class UserForm(forms.Form):
    username = forms.CharField()

    def clean_username(self):
        data = self.cleaned_data
        try:
            User.objects.get(username = data['username'])
        except User.DoesNotExist:
            return data['username']
        raise forms.ValidationError('This username is already taken.')

Here we can validate that the usernames are not repeated.

5.

Prob. You want to create a field which has cross field validations.

Ans. Create a field with a .clean

class UserForm(forms.Form):
    username = forms.CharField()

    password1 = forms.PasswordField()
    password2 = forms.PasswordField()

    def clean(self):
        data = self.cleaned_data
        if "password1" in data and "password2" in data and data["password1"] != data["password2"]:
            raise forms.ValudationError("Passwords must be same")

6.

Problem.

You need a form the fields of which depends on some value in the database. Eg. The field to be shown are customisable per user.

Create a form dynamically

def get_user_form_for_user(user):
        class UserForm(forms.Form):
            username = forms.CharField()
            fields = user.get_profile().all_field()
            #Use field to find what to show.

This post provides much more details

7.

Prob. You need to create a Html form which writes to multiple Django models.

Ans. Django forms are not a one to one mapping to Html forms.

#in forms.py
class UserForm(forms.ModelForm):
    class Meta:
        model = User
        fields = ["username", "email"]

class UserProfileForm(forms.ModelForm):
    class Meta:
        model = UserProfile

#in views.py
def add_user(request):
    ...
    if request.method == "POST":
        uform = UserForm(data = request.POST)
        pform = UserProfileForm(data = request.POST)
        if uform.is_valid() and pform.is_valid():
            user = uform.save()
            profile = pform.save(commit = False)
            profile.user = user
            profile.save()
            ....
    ...

#in template
<form method="post">
    {{ uform.as_p }}
    {{ pform.as_p }}
    <input type="submit" ...>
</form>

8.

Prob. You want to use multiple forms of same type on one page.

Ans.

a. If you want a datagrid style ui, use formset.

from django.forms.formsets import formset_factory
forms = formset_factory(UserForm, extra = 4)
#

Formsets are described much more comprehensively here

b. If you do not need a datagrid style ui, use prefix argument to forms.

Eg. you have a survey app, and you want a page with all questions from that survey displayed.

#IN views.py
def survey(request, survey_slug)
    ...
    questions = survey.questions.all()
    question_forms = []
    for question in questions:
        qform = QuestionForm(question=question, prefix = question.slug)
        question_forms.append(qform)
        ...
    if request.method == "POST":
        for question in questions:
            qform = QuestionForm(question=question, prefix = question.slug, data = request.POST)
        #Validate and do save action
        ...
    ...

Do you subscribe to our feed? We recently made a full text feed available, so if you are using the old feed, you should change it. Subscribe now.


Related Posts


Can we help you build amazing apps? Contact us today.

Comments

kevin

Nice round up of use cases and solutions. This is a good reference for noobs and experienced Django devs. Thanks.

commmenttor
Dave 14th Jan., 2010

Cool post. Thanks. Suggestion for future post: How to use static values in a formset. For example display a list view of items, but with an enable/disable check box on each item. I tried using a formset containing a BooleanField, but could not figure out how to add static fields to it. And for extra credit, update check box value via AJAX.

commmenttor
Zach 14th Jan., 2010

Thanks for this post. Very helpful!

commmenttor
shabda

Dave:

I dont think you can use formset for that, you should use the second method, and set prefixes manually, eg

for question in survey.questions.all():
qform = SurveyForm(survey, prefix = question.slug)
if questions.is_optional:
qform.set_optional()

Etc

commmenttor
nix

I like Django! Thanks for info about this

commmenttor
geo

Hey, at the code snippet at number 4, shouldn't it be "except User.DoesNotExist" instead of "User.DoesNotExist:" ?

commmenttor
shabda

@geo: Thanks, updated the posts.

commmenttor
Andy 19th Jan., 2010

Foe no. 6, the definition of the class UserForm changes depending on which employee is involved.
if I just create an new instance of UserForm, how does Python know which definition to use?

commmenttor
Nicola Culli 9th April, 2010

Hi, i tried that example and i didn't get one part working from the beginning, how come it doesn't work for me?

commmenttor
Durand 11th Dec., 2011

Thanks, this helped me a lot!

commmenttor
jain 13th Jan., 2012

in 7th form . why do u leav some dots?

commmenttor
jain 13th Jan., 2012

in 7th form . why do u leav some dots..?

commmenttor
Arun 29th Jan., 2012

Very good examples for my Team to learn from.
Also i see that this blog is developed in Zinnia... :)

commmenttor
ayse 3rd Aug., 2012

plz can you show how to configure admin.py for forms
thanks.

commmenttor
elvis kofi 30th Sept., 2012

this is the coolest django blog i have seen in a while

commmenttor
Jayaprakash

Good post, understood the basics of Django forms. Thanks.

commmenttor
Jayaprakash

Cool post, understood the basics of Django forms. Thanks.

commmenttor
Fino ad oggi economici da sole Ray Ban ?? Hai bisogno di ricerca

Doing things with Django forms - Agiliq Blog | Django web app development

commmenttor

Reactions

uswaretech_blog

Doing things with Django forms: Forms are one of the best features of Django. (After models, admin, url routing.. http://bit.ly/6lNinJ

This comment was originally posted on Twitter

djangobot

Shabda Raaj: Doing things with Django forms http://bit.ly/5l5BRq

This comment was originally posted on Twitter

YCHackerNews

Doing things with Django forms: http://bit.ly/4VdFYV Comments: http://bit.ly/7nRyXQ

This comment was originally posted on Twitter

tek_news

HNews: Doing things with Django forms http://bit.ly/8wedHP

This comment was originally posted on Twitter

Apreche

via del.icio.us: The real guide to django forms http://bit.ly/6EdrkW

This comment was originally posted on Twitter

uswaretech

New blog post. Doing things with Django forms. http://bit.ly/7YRyoJ

This comment was originally posted on Twitter

readelicious

Django Forms: http://bit.ly/7Kyun6

This comment was originally posted on Twitter

JimH10

Good link; thanks. There are a lot of things in here that took me quite a while to dope out.

This comment was originally posted on Reddit

webstartupgroup

StartupNews: Doing things with Django forms http://bit.ly/74I3Vt

This comment was originally posted on Twitter

djangopro

Doing things with Django forms http://bit.ly/8wedHP

This comment was originally posted on Twitter

recurser

Nice summary.

This comment was originally posted on Hacker News

old-gregg

Forms are the biggest difference between Rails itself and Rails-inspired Python frameworks (I’m talking about Pylons’s default helpers, Toscawidgets and Django here)After working with Rails for 3 years I am absolutely don’t get the need for "form" classes. And indeed, judging by open sourced projects and posted code examples, submit handlers in Django and Pylons always look insanely complex as compared to Rails.

This comment was originally posted on Hacker News

andreisavu

Doing things with Django forms http://ff.im/-ejP4O

This comment was originally posted on Twitter

kgrin

Django isn’t Rails-inspired – they were developed at around the same time, with no real awareness of each other (at first).As to the merits of "form" classes and post handlers, I think the complexity is only there if you need it, if you’re doing something more interesting (read: complex) than CRUD-type inserts/updates and basic validation (if that’s all you’re doing, ModelForms are pretty close to magical and light on syntax).

This comment was originally posted on Hacker News

paddie

Agreed, forwarded this to a couple of my friends who have just started developing for Django.. very nice examples

This comment was originally posted on Reddit

dbreen

These tips would have been nice as a django noob. I think they really belong in the docs. http://bit.ly/7bfNsH !a #django !import (maybe?)

This comment was originally posted on Twitter

ubernostrum

Shameless self-promotion: * [Intro to the forms library, part 1](http://www.b-list.org/weblog/2007/nov/22/newforms/) (from not long after it was added, back when it was `django.newforms` instead of just `django.forms`) * [Part 2](http://www.b-list.org/weblog/2007/nov/23/newforms/) * [Dynamic forms](http://www.b-list.org/weblog/2008/nov/09/dynamic-forms/)

This comment was originally posted on Reddit

djangostories

Doing things with Django forms
: http://bit.ly/8UIrOz

This comment was originally posted on Twitter

JimH10

I have those bookmarked; they were a big help also. Thank you for those.

This comment was originally posted on Reddit

pythonstories

Doing things with Django forms http://bit.ly/8QKWmx

This comment was originally posted on Twitter

hrjn_rss

Doing things with Django forms: Comments http://url4.eu/18MPU

This comment was originally posted on Twitter

paddie

Dude, where was this 1 month ago when I really needed it?! Shit, bookmarked!

This comment was originally posted on Reddit

cjmaynar

I’ve got a question for you. I’ve got a dynamic form set up with a foreign key pointing to another model. I’ve been unable to find an easy way of including an add button into the form so that the user can add an entry to the other model and have it immediately reflected on the form that they were editing before. The way i’m envisioning it, it would work similar to the way that kind of thing is handled in the admin section. Could you perhaps point me in the right direction?

This comment was originally posted on Reddit

kaveri

Django forms (and their non-Django counterpart, WTForms) are very easy to use, with a declarative syntax.The advantage is that validation is decoupled from models. Often you need to handle validation which doesn’t directly involve a single model – for example sending an email, or handling updates to a number of models. This saves you having to litter your controller/views with validation code.

This comment was originally posted on Hacker News

mdgArt

http://icio.us/xwuxlg

This comment was originally posted on Twitter

scorpion032

Perhaps, a side block next to articles, linking to other articles in the same tag, and some random articles might be helpful?

This comment was originally posted on Reddit

djangostories

Doing things with Django forms: http://bit.ly/6ZStT4

This comment was originally posted on Twitter

jsuntheimer

Doing things with Django forms — The Usware Blog – Django Web Development: Tags: django Posted by: jsuntheimer http://bit.ly/6ze24s

This comment was originally posted on Twitter

metoikos

Doing things with Django forms — The Usware Blog – Django Web Development http://ff.im/-eq838

This comment was originally posted on Twitter

delicious50

Doing things with Django forms — The Usware Blog – Django Web Development http://bit.ly/8TPjdM forms django tutorial

This comment was originally posted on Twitter

virhilo

#django: http://uswaretech.com/blog/2010/01/doing-things-with-django-forms/

This comment was originally posted on Twitter

Post a comment Name :

Email :

Your site url:

Comment :

© Agiliq, 2009-2012