Changes between Initial Version and Version 1 of CookBookManipulatorWithHiddenFields


Ignore:
Timestamp:
Aug 19, 2005, 5:11:00 PM (19 years ago)
Author:
Adam Endicott <leftwing17@…>
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • CookBookManipulatorWithHiddenFields

    v1 v1  
     1= CookBook - Manipulator With Hidden Fields =
     2
     3== Description ==
     4I needed to present a form to allow a user to create a new object. However, some fields in the object were already known by the system (such as the user who was adding the object). Rather than presenting these fields to the user, I created a custom manipulator that allowed me to hide them. The example will be a user creating a new message.
     5
     6== Code ==
     7Here's a simple Message model as an example:
     8{{{
     9#!python
     10class Message(meta.Model):
     11    fields = (
     12        meta.CharField('title', maxlength=255),
     13        meta.TextField('body'),
     14        meta.DateTimeField('postDate', auto_now_add=True),
     15        meta.ForeignKey(auth.User),
     16        )
     17}}}
     18Here's the custom manipulator that allows us to hide the user and project fields. It inherits from the model's pre-made !AddManipulator, the iterates over the fields replacing some of them with a formfields.!HiddenField
     19{{{
     20#!python
     21class MessageManipulator(messages.AddManipulator):
     22    def __init__(self):
     23        # Set everything up initially using the built in manipulator
     24        messages.AddManipulator.__init__(self)
     25        newFields = []
     26        # Iterate over all the fields looking for the ones I want to hide,
     27        # and replacing them with HiddenFields
     28        for field in self.fields:
     29            if field.field_name in ('user_id',):
     30                field = formfields.HiddenField(field.field_name,
     31                                               field.is_required,
     32                                               field.validator_list)
     33            newFields.append(field)
     34        self.fields = newFields
     35}}}
     36Here's the view code:
     37{{{
     38#!python
     39def addMessage(request):
     40    manipulator = MessageManipulator()
     41    if request.POST:
     42        newData = request.POST.copy()
     43        errors = manipulator.get_validation_errors(newData)
     44        if not errors:
     45            manipulator.do_html2python(newData)
     46            newMessage = manipulator.save(newData)
     47            return HttpResponseRedirect(newMessage.get_absolute_url())
     48    else:
     49        errors = {}
     50        # Add the the data that you already know and don't want to burden
     51        # the user with here.
     52        newData = {'user_id': request.user.id,}
     53    form = formfields.FormWrapper(manipulator, newData, errors)
     54    t = template_loader.get_template('addMessage')
     55    c = Context(request, {'form': form,})
     56    return HttpResponse(t.render(c))
     57}}}
     58Here's part of the template code. {{ form.user_id }} places the hidden field in the form. It will be populated with the correct data because we set that in newData above. Title and Body are other fields defined in the Message model. messages.!AddManipulator took care of populating those correctly.
     59{{{
     60<form method="post" action=".">
     61{{ form.user_id }}
     62<p>
     63    <label for="id_title">Title:</label> {{ form.title }}
     64    {% if form.title.errors %}*** {{ form.title.errors|join:", " }}{% endif %}
     65</p>
     66<p>
     67    <label for="id_body">Body:</label> {{ form.body }}
     68    {% if form.body.errors %}*** {{ form.body.errors|join:", " }}{% endif %}
     69</p>
     70}}}
     71And the HTML generated from this template:
     72{{{
     73<form method="post" action=".">
     74<input type="hidden" id="id_user_id" name="user_id" value="2" />
     75<p>
     76    <label for="id_title">Title:</label> <input type="text" id="id_title"
     77class="vTextField required" name="title" size="30" value="" maxlength="255" />
     78</p>
     79<p>
     80    <label for="id_body">Body:</label> <textarea id="id_body"
     81class="vLargeTextField required" name="body" rows="10" cols="40"></textarea>
     82</p>
     83}}}
     84
     85Enjoy!
Back to Top