Using Manipulators can be rather cumbersome. Here is a class to simplify the process.
from django import forms from django.core import validators class Manipulator(forms.Manipulator): default = {} done = False def __bool__(self): return self.done def get_data(self, request): return request.POST def get_form(self, data, errors): return forms.FormWrapper(self, data, errors) def process(self, request): data = self.get_data(request) if data: new_data = data.copy() errors = self.get_validation_errors(new_data) if not errors: self.do_html2python(new_data) self.done = True return self.complete(request, new_data) else: errors = {} new_data = self.default self.form = self.get_form(new_data, errors) return self.form def complete(self, request, data): self.save()
Now to use: you should subclass it and fill in the necessary methods ("__init__
" and "complete
"), and provide fields:
class PollEdit(Manipulator): # Provide the fields. fields = ( forms.TextField("title", maxlength=32, is_required=True), forms.TextField("question", maxlength=128, is_required=True), ) def __init__(self, poll): # We could also provide our fields here, which is usefull if you have # custom validators that you need to reference off of "self." # Save a reference to our poll. self.poll = poll # Set our default dictionary to match our poll object. # That way the data populating the fields will match our current poll. self.default = poll.__dict__ def complete(self, request, data): # This is executed after the user submits valid data. # Set the poll's title to the user-submited 'title' in our data. self.poll.title = data['title'] # Same with 'question' self.poll.question = data['question'] # Don't forget to save. self.poll.save()
Usage of the final Manipulator is quite simple:
def edit_poll(request, id): poll = get_object_or_404(Poll, pk=id) # Get our poll object. manipulator = PollEdit(poll) # Create the manipulator. manipulator.process(request) # Process the request. if (manipulator.form): # Should we render the form? return render_to_response('polls/edit_form', {'form': manipulator.form}) else: # Otherwise, redirect to the poll view page. return HttpResponseRedirect("/polls/%d" % poll.id)
Here's a custom Add Manipulator. Here we can sub-class the first manipulator, so that the fields are the same:
class PollAdd(PollEdit): def __init__(self): # Set our default values. self.default = {'title': "Unnamed", 'question': 'Insert your question here.'} def complete(self, request, data): # Create a new poll with our data. poll = polls.Poll(title=data['title'], question=data['question']) poll.save() # It'd be nice to be able to get the poll back. return poll
And here's the add usage:
def add_poll(request): manipulator = PollAdd() # Create the manipulator poll = manipulator.process(request) # Process the request if (manipulator.form): # Should we render the form? return render_to_response('polls/new_form', {'form': manipulator.form}) else: # Otherwise, redirect to the poll view page. return HttpResponseRedirect("/polls/%d" % poll.id)
Attachment
Sometimes Trac annoys the hell out of me. Use the bottom attachment there. I can't fix this error.
Attachments (2)
-
quickform.tar.gz
(3.1 KB
) - added by 18 years ago.
A contrib app that provides this class and a tag to quickly render forms.
-
quickforms.tar.gz
(3.0 KB
) - added by 18 years ago.
A contrib app that provides the above Manipulator class and a tag to quickly render forms.
Download all attachments as: .zip