• Author: guille
  • Published: Sep 12th, 2006
  • Comments: 2

Wrapping generic views

glassesAfter programing a simple application with the generic views (create_object and update_object), I was faced with the following demand: A client wanted to use checkboxes instead of the standard select list Django offers when using generic views. Surprisingly enough, this option does not seem to be shipped as an option in the generic views.

The main idea is to write the form by hand and then modify the request.POST to transform it to the needs of the generic views. We want to convert the
request.POST from something that looks like this: {‘classesFirst’: ['on'], ‘classesSecond’: ['on'], ‘classesThird’: ['on']} to something that lookslike this: {‘classes’: ['First', 'Second', 'Third']}. Of course, this could have been done by writting my own form, but I wanted to reuse the generic views.

We first write the transformer (the equivalent of the prepare() for the CheckboxSelectMultipleField):

def get_classes_selection(new_data):
       return [item[6:] for item in new_data.keys()
               if item.startswith('classes')]

and the view:

def create_member(request,template_name=None,post_save_redirect=None):
    if request.POST:
        new_data = request.POST.copy()
        new_data.setlist('classes',get_classes_selection(new_data))
        request.POST = new_data.copy()
    else:
        new_data={}
    return django.views.generic.create_update.create_object(request, Member,
                  template_name=template_name,
                  post_save_redirect=post_save_redirect,
                  extra_context={'classes':Class.objects.all()})

We can then write the part of the template that concerns the form:

<form action="." method="post">
  <label for="id_name">Name:</label>
 {{ form.name }}{% if form.name.errors %}*** {{ form.name.errors|join:", " }}{% endif %}
  {% for class in classes %}
    <ul><li><input type="checkbox" id="id_classes{{ class.name }}" name="classes{{ class.id }}" > <label for="id_classes{{ class.name }}">{{ class.name }}</label></li></ul>
  {% endfor %}
  {% if form.classes.errors %}*** {{ form.classes.errors|join:", " }}{% endif %}
  <input type="submit" value="Create"/>
</form>

The view for the update_member is very similar, as is its template.

This is a very simple application that shows how to reuse the generic views that are shipped with Django. It is intended simply as another example. For complete information about how to extend a generic view, look at this excellent article by Malcom Tredinnick.

Tags:

2 Responses to “Wrapping generic views”


  1. lurcas
    on Jun 17th, 2007
    @ 17:09

    Sorry, I think another way!!!!!


  2. aucziy
    on Jun 17th, 2007
    @ 18:20

    Well done boys! Great news!

Leave a Reply

© 2006,2007,2008,2009,2010 Guillermo Fernández Castellanos | Header images by Nick Lobeck