30
Django Forms just the tip of the ice burg

Django forms

Embed Size (px)

DESCRIPTION

 

Citation preview

Page 1: Django forms

Django Formsjust the tip of the ice burg

Page 2: Django forms

Objectives Explore Django forms API Review the Django forms documentation Create forms using the Django Forms API

Page 3: Django forms

Out of the Box Form handling django library Automatically displays HTML form elements Validates submitted data Displays validation errors Automatically converts submitted data into relevant data

types.

Page 4: Django forms

Getting Started1. forms.py

2. template rendering

3. models.py

4. views.py

Page 5: Django forms

forms.py Forms are composed of fields

from django import forms

class ContactForm(forms.Form):

name = forms.CharField()

email = forms.EmailField()

age = forms.IntegerField()

Page 6: Django forms

forms.py - fieldsEach field has custom validation logic and other useful hooks.

name = forms.CharField(

label =“Full Name”,

max_length = “50”,

)

email = forms.EmailField(

max_length = “100”,

required = “false”

)

age = forms.IntegerField(

min_value = 18,

)

Page 7: Django forms

forms.py - widgetsEach field has a default widget which serves to render html.

name = forms.CharField(

label =“Full Name”,

max_length = “50”,

widget = forms.TextInput(

attrs = { ‘size’ : ’50’, ‘class’ = ‘customClass’ }

)

)

email = forms.EmailField(

max_length = “100”,

required = “false”,

widget = forms.HiddenInput()

)

age = forms.IntegerField(

min_value = 18,

widget = forms.TextInput()

error_messages={’invalid': ’Only numbers please.'}

)

Page 8: Django forms

Instantiation : Bound vs Unbound

Unbound forms don’t have data associated with them, but then can be rendered.

form = ContactForm()

Bound forms have specific data associated, which can be validated.

form = ContactForm(data = dataDict)

Page 9: Django forms

Initial Data Data displayed only in unbound forms, and are not used as

fallback values if a particular value isn’t provided.

Initial != Default

Can be set two different ways :

1. Set it in the field declaration of your form.

age = forms.IntegerField(initial=18)

2. Set it when you instantiate your form.

form = ContactForm(initial = initialDict)

Page 10: Django forms

Form Validation Processform.is_valid()

form._get_errors()

form.full_clean()

form._clean_fields()

for field in form.fields:

value = widget.value_from_datadict(data, files, name)

field.clean(value)

field.to_python(value)

field.validate(value)

field.run_validators(value)

field.clean_fieldname()

form._clean_form()

form.clean()

Form validation

Widget

Field

form

Page 11: Django forms

Form Validation Overview Only bound forms may be validated Validation is triggered when form.is_valid() is called Validated, cleaned data is stored in form.cleaned_data Perform the full validation cycle by calling form.full_clean()

Page 12: Django forms

Field Validating Three phases for fields: To Python, Validation, and Cleaning If validation raises an Error, cleaning is skipped Validators are callables that can raise a ValidationError Django inlcludes generic ones for common tasks.

URLS, Min/Max Value, Email, etc.

Page 13: Django forms

Validators - definingA callable that takes a value and raises a ValidationError; can be useful for reusing validation logic.

App/validators.py

from django.core.exceptions import ValidationError

Import re

def validate_full_name(value):

if len(re.findall(r'\w+', value)) < 2:

raise ValidationError(u’%s is not a full name.’ % value)

Page 14: Django forms

Validators - usingfrom django import forms

from projectgroup.project.application.validators import validate_full_name

class ContactForm(forms.Form):

name = forms.CharField(

label =“Full Name”,

max_length = “50”,

validators = [validate_full_name]

)

email = forms.EmailField(

max_length = “100”,

required = “false”

)

age = forms.IntegerField(

min_value = 18,

)

Page 15: Django forms

Field Cleaning .clean_fieldname() is called after validators Input has already been converted to Python objects Methods can still raise ValidationError Methods must return the cleaned_value

Page 16: Django forms

Specific Field Cleaning Examplefrom django import forms

from projectgroup.project.application.validators import validate_full_name

class ContactForm(forms.Form):

# Everything as before

def clean_email(self):

data = self.cleaned_data.get(‘email’, ‘’)

if ‘gmail.com’ not in data:

raise forms.ValidationError(“Why you no like gmail?”)

# always return the cleaned data, whether you have change

# it or not

return data

Page 17: Django forms

Form Validation .clean() perform cross-field validation Called even if errors were raised by Fields Must return the cleaned data dictionary ValidationError’s raised by .clean() will be grouped in

form.non_field_errors() by default

Page 18: Django forms

Cross-field Cleaning Examplefrom django import forms

from projectgroup.project.application.validators import validate_full_name

class ContactForm(forms.Form):

# Everything as before

def clean (self):

cleaned_data = super(ContactForm, self).clean()

age = cleaned_data.get(“age”)

email = cleaned_data.get(“email”)

if not age and not email:

raise forms.ValidationError(“Age and email are required.”)

return cleaned_data

Page 19: Django forms

Rendering : Primary ModesThere are three primary output modes :

1. form.as_p()

<p>

<label for=“name”>Name</label>

<input type=“text” id=“name” name=“name” size=“50”/>

</p>

<p>

<label for=“email”>Email</label>

<input type=“text” id=“email” name=“email” size=“50”/>

</p>

<p>

<label for=“age”>Age</label>

<input type=“text” id=“age” name=“age” size=“3”/>

</p>

2. form.as_ul()

3. form.as_table()

Page 20: Django forms

Rendering : Controlled Output

{{ field.non_form_errors }}

{% for field in form %}

<div class=“fieldWrapper”>

{{ field.errors }}

{{ field.label_tag }}: {{ field }}

</div>

{% endfor %}

Page 21: Django forms

Manually Created<form id=“contact” action=“” method=“get”>

<p>

<label for=“name”>Name</label>

<input type=“text” id=“name” name=“name” size=“50”/>

</p>

<p>

<label for=“email”>Email</label>

<input type=“text” id=“email” name=“email” size=“50”/>

</p>

<p>

<label for=“age”>Age</label>

<input type=“text” id=“age” name=“age” size=“3”/>

</p>

<input type=“submit” name=“save”/>

</form>

Page 22: Django forms

Dynamically Created<form id=“contact” action=“” method=“get”>

{{ form.as_p }}

<input type=“submit” name=“save”/>

</form>

<form id=“contact” action=“” method=“get”>

{{ field.non_form_errors }}

{% for field in form %}

<div class=“fieldWrapper”>

{{ field.errors }}

{{ field.label_tag }}: {{ field }}

</div>

{% endfor %}

<input type=“submit” name=“save”/>

</form>

Page 23: Django forms

Model Forms modelForms map a model to a form validation includes model validators Supports creating and editing instances Key differences from forms

There will be a field for a primary key (id) New save() method New instance attribute

Page 24: Django forms

Model Form Exampleapp/models.py

from django import models

class Contact(models.Model):

name = models.CharField(max_length=50)

email = models.EmailField()

age = models.IntegerField()

app/forms.py

from django import forms

from grp.prj.app.models import Contact

class ContactForm(forms.Modelform):

class Meta:

model = Contact

Page 25: Django forms

Limiting Fields Specify fields to expose, or fields to exclude

app/forms.py

from django import forms

from grp.prj.app.models import Contact

class ContactForm(forms.ModelForm):

class Meta:

model = Contact

fields = ('name', 'email',)

class ContactForm(forms.ModelForm):

class Meta:

model = Contact

exclude = (’age',)

Page 26: Django forms

Instantiating Model Forms Like before, we may have bound and unbound Model Forms

Unbound

mform = ContactForm()

Bound

mform = ContactForm(instance=Contact.objects.get(id=2) )

Page 27: Django forms

Handling forms in views.py1. Import your form(s)

2. Within your view function1. Check for submission(GET or POST).

1. If submitted1. bind the form to the data.

2. Validate.

1. If its valid, do stuff.

2. Otherwise let it remain unbound.

3. Pass form to the context

4. Render your page.

Page 28: Django forms

views.py examplefrom grp.prj.app.forms import ContactForm

def contactView(request):

context = {}

contactPDA = Dpdpcntc()

initials = {

‘age' : ’18'

}

#instantiate

if request.GET.get(‘submit’):

form = ContactForm(data = request.GET)

if form.is_valid():

….

else:

form = ContactForm(initial=initials)

context[‘form’] = form

return render_to_response(…)

Import Form

Check for submission

Bind Form

Form Validation

Unbound Form

Render HTMLForm in Context

Page 29: Django forms

views.py – other examplesif request.GET.get(‘submit’):

form = ContactForm(request.GET)

if form.is_valid():

….

else:

form = ContactForm(initial=initials)

if request.GET:

form = ContactForm(request.GET)

if form.is_valid():

….

else:

form = ContactForm(initial=initials)

form = ContactForm(data=request.GET or None, initial=initials)

if form.is_valid():

….

Page 30: Django forms

FinQuestions?