Changing field widget attributes from view code

Posted by – February 3, 2009

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.

Share

2 Comments on Changing field widget attributes from view code

  1. Joylin says:

    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.

  2. rogerio says:

    Have you tried form.fields['speed'].widget.attrs['readonly'] = ‘readonly’ ?

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>