I wrote about newforms library before. The library was a big step in Django form displaying and validating.
The first approach was to use forms.form_for_model() and forms.form_for_instance() respectively.
As Django programmer I found this a little confusing. Both were similar. The only difference was that form_for_instance() took an object instance for saving instead
of creating a new one. Recently django developers came up with a great idea - forms.ModelForm which combines both into one. It's great!
Just take a look at the example below.
Assume you want to create a new view function for creating & editing an object.
You only want to edit 3 fields (name, last_name, status). Also, you've created a
customized field type for "status", and want to use that.
Scenario #1: (forms.form_for_model && forms.form_for_instance)
def f_callback(field, **kwargs):
if field.name == "status":
return MyStatusField(**kwargs)
else:
return field.formfield(**kwargs)
def create_edit_customer(request, customer_id=None):
# check if object_id is None and if object exists
if object_id is None:
CustomerForm = forms.form_for_model(Customer,
formfield_callback=f_callback,
fields=('name','last_name','status')
else:
customer = get_object_or_404(Customer, id=customer_id)
CustomerForm = forms.form_for_instance(customer,
formfield_callback=f_callback,
fields=('name','last_name','status')
if request.method == "POST":
form = CustomerForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect('customer/added/')
else:
form = CustomerForm()
return render_to_response("customers/customer_form.html", {'form' : form })
You could create your own form_for_model & form_for_instance subclass (using forms.BaseForm for example), but it would be too complicated. Hope you don't use this form often :-)
Scenario #2 (ModelForm)
1. Longer version.
class CustomerModelForm(forms.ModelForm):
class Meta:
model = Customer
fields = ('name','last_name','status')
status = MyCustomerField()
def create_edit_customer(request, customer_id=None):
if customer_id is not None:
customer = get_object_or_404(Customer, id=customer_id)
else:
customer = None
if request.method == "POST":
form = CustomerModelForm(data=request.POST, instance=customer)
if form.is_valid():
form.save()
return HttpResponseRedirect("/customer/added/")
else:
form = CustomerModelForm(instance=customer)
return render_to_response("customers/customer_form.html", {'form' : form })
2. Shorter version.
class CustomerModelForm(forms.ModelForm):
class Meta:
model = Customer
fields = ('name','last_name','status')
status = MyCustomerField()
def create_edit_customer(request, customer_id=None):
if customer_id is not None:
customer = get_object_or_404(Customer, id=customer_id)
else:
customer = None
form = CustomerModelForm(data=request.POST or None, instance=customer)
if form.is_valid():
form.save()
return HttpResponseRedirect("/customer/added/")
return render_to_response("customers/customer_form.html", {'form' : form }
We are using one form class for editing & creating objects.
We can also subclass CustomerModelForm and edit/change the way the form looks
and behave (by adding field clean() method.
Django forms library looks better each day :-)
No comments:
Post a Comment