Models
Links
Customise
Attribute
To add an attribute to a form field:
class ItemViewForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(ItemViewForm, self).__init__(*args, **kwargs)
count = 0
for name in self.fields:
count = count + 10
self.fields[name].pk_count = count
To use the pk_count
attribute in the template:
{{ field.field.pk_count }}
Field
To add a field to a model form:
from django.forms.fields import ChoiceField
from django.forms.widgets import RadioSelect
ACCEPT_REJECT = [
['Accept', 'Accept'],
['Reject', 'Reject']
]
class ReviewForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(ReviewForm, self).__init__(*args, **kwargs)
self.fields.update({
'accept_or_reject': ChoiceField(
widget=RadioSelect(),
choices=ACCEPT_REJECT
),
})
Note: Don’t forget to add this field to the template (if you are not looping through all the fields already).
Read Only
Two options - just display the field on the template:
{{ form.instance.village.county.name }}
… or… To make a form read only:
class ItemViewForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(ItemViewForm, self).__init__(*args, **kwargs)
for name in self.fields:
widget = self.fields[name].widget
# If a select widget, change to a TextInput widget.
if type(widget) == forms.Select:
self.fields[name].widget = forms.TextInput()
# Set the readonly attribute of the widget to true.
self.fields[name].widget.attrs['readonly'] = True
Widget
To change the widget and set attributes for a form field:
from django.forms.widgets import Select
class ItemForm(forms.ModelForm):
class Meta:
model = ItemModel
widgets = {
'description': Select(
attrs={
'range': '12.50, 13.75, 14.01',
}
),
}
Forms from Models
app-name/forms.py
:from django.forms import ModelForm from models import Publisher class PublisherForm(ModelForm): class Meta: model = Publisher fields = ('message',)
Note: If you don’t want to have a field appearing on the form, set
editable=False
on the model field… or… use thefields
attribute to list fields to include… (orexclude
).app-name/views.py
:from django.http import HttpResponseRedirect from django.shortcuts import render_to_response from forms import PublisherForm def add_publisher(request): if request.method == 'POST': form = PublisherForm(request.POST) if form.is_valid(): form.save() return HttpResponseRedirect('/add_publisher/thanks/') else: form = PublisherForm() return render_to_response('books/add_publisher.html', {'form': form})
Note: To initialise a form with a model instance (object):
Initialise the form with an existing object:
feature_object = Feature.objects.get(slug=feature) form = FeatureForm(instance=feature_object)
When saving the object, initialise the form with the original object:
feature_object = Feature.objects.get(slug=feature) if request.method == 'POST': form = FeatureForm(request.POST, instance=feature_object) if form.is_valid():
To display the form, use this (minimal) html:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"> <html lang="en"> <head> <title>New Task</title> </head> <body> <h1>New Task</h1> <form action="." method="POST"> {% csrf_token %} <table> {{ form.as_table }} </table> <p><input type="submit" value="Submit"></p> </form> </body> </html>
Save
To override the form save
method:
def save(self, force_insert=False, force_update=False, commit=True):
instance = super(MyForm, self).save(commit=False)
# do some custom stuff
instance.flag1 = 'flag1' in self.cleaned_data['multi_choice'] # etc
if commit:
instance.save()
return instance
See stackoverflow, Overriding the save method in Django ModelForm and stackoverflow, Django: How to override form.save()