Changing field widget attributes from view code
Yesterday I finally wrote my first Django application, this application is a basic crud that contains two pages, one to list costumers and another to change costumer data.
My biggest challenge was related with some form features, with Django forms you can programatically create a view form that contains several fields with its constraints and optionally associate a Django widget with this field. Django forms also have a very powerful validation engine and some form field constraints must be defined for this purpose.
This application uses the same page for two purposes, to add new data or edit data, in this scenario I must use a hidden field to be used as flag indicating in which mode the page is, adding or editing data, I must also change the readonly attribute of input widget used by costumer id form field since the user can’t change costumer id.
Each form contains only fields definition and some meta properties, nothing more, a example of django forms is something like we have below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | from django import forms from app.costumer.models import Costumer class CostumerForm(forms.ModelForm): id = forms.CharField(max_length=13, required=True, label = 'ID', widget=forms.TextInput(attrs={ 'class':'custom', 'size':'15', 'onblur':'return checkNumericKey(event, false);', 'title':'Type costumer id and press [TAB].' }) ) name = forms.CharField(max_length=80, required=True,label = 'Name', widget=forms.TextInput(attrs={ 'class':'custom', 'size':'45', 'onkeydown':'upperCaseInput(this)', 'title':'Type costumer name and press [TAB].' }) ) class Meta: model = Costumer |
But the code above is very static and I need change a specific attribute on the widget attached to id field to make this field as readonly, in order to do it, I must perform the changes on widget attributes during execution of view code like we have below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | from django.template import RequestContext from django.core.urlresolvers import reverse from django.shortcuts import render_to_response from app.costumer.models import Costumer from app.costumer.forms import CostumerForm from django.http import HttpResponseRedirect def save(request): if request.POST.get('new', None): form = CostumerForm(request.POST,instance=None) else: costumer = Costumer.objects.get(pk=request.POST['id']) form = CostumerForm(request.POST, instance= costumer) if form.is_valid(): form.save() else: if request.POST.get('new', None) is None: form.fields['id'].widget.attrs['readonly'] = 'readonly' return render_to_response('costumer/managedata.html', { 'form': form, 'novo': request.POST.get('novo', None), }, context_instance=RequestContext(request)) return HttpResponseRedirect(reverse('crud.app.costumer.views.list')) |
In the example above we are setting the id field as readonly (line 19) when form has validation errors.
hi,
The readonly attribute is already set in the form
speed = forms.IntegerField(widget=forms.TextInput(attrs={\’readonly\’:True}))
I need to remove the readonly in my view. How can i do it?
I tried
form.fields[\'speed\'].widget.attrs[\'readonly\'] = False\’
But this doesnt work. Please help.
June 9th, 2009 | #
Have you tried form.fields['speed'].widget.attrs['readonly'] = ‘readonly’ ?
June 10th, 2009 | #