Version 7 (modified by anonymous, 13 years ago) (diff)


Using Manipulators can be annoying and confusing, use this to create simple, elegant ones:

from django.core import formfields, validators

class Manipulator(formfields.Manipulator):
    default = {}
    done = False
    def getData(self, request):
        return request.POST
    def getForm(self, data, errors):
        return formfields.FormWrapper(self, data, errors)
    def process(self, request):
        data = self.getData(request)
        if data:
            new_data = data.copy()
            errors = self.get_validation_errors(new_data)
            if not errors:
                self.done = True
                return self.complete(request, new_data)                
            errors = {}
            new_data = self.default
        self.form = self.getForm(new_data, errors)
        return self.form

    def complete(self, request, data):

Now to use, subclass it, and fill in the necessary methods ("__init__" and "complete"), also give it the fields:

class PollEdit(Manipulator):
    fields = (
        formfields.TextField("title", maxlength=32, is_required=True),
        formfields.TextField("question", maxlength=128, is_required=True),
    def __init__(self, poll):
        # You can also define your fields here, if you'd like.
        self.poll = poll
        ## Luca M.: 03/09/2006 
        ## I've to uncomment the following line to fill the form with the current data
        # self.default = poll.__dict__
        ## Is this correct ? I'm using django 0.91
    def complete(self, request, data):
        self.poll.title = data['title']
        self.poll.question = data['question']

Usage of the final Manipulator is quite simple:

def edit_poll(request, id):
    poll = polls.get_object(pk=id)      #Assume it works
    manipulator = PollEdit(poll)
    form = manipulator.process(request)    #Process returns a form if it's needed
    if (form):
         return render_to_response('polls/edit_form', {'form': form})
         return HttpResponseRedirect("/polls/%d" %

Here's a custom Add Manipulator I like to build off of first, so that the fields are the same:

class PollAdd(PollEdit):        
    def __init__(self):
        self.default = {'title': "Unnamed", 'question': 'Insert your question here.'}
        #This sets your default values.
    def complete(self, request, data):
        poll = polls.Poll(title=data['title'], question=data['question'])
        return poll

And here's the add usage:

def add_poll(request):
    manipulator = PollAdd()
    result = manipulator.process(request)
    if (manipulator.done): #Are we done processing?
         return HttpResponseRedirect("/polls/%d" %
    else: #Otherwise, place the form.
         return render_to_response('polls/new_form', {'form': manipulator.form})

Attachments (2)

Download all attachments as: .zip

Back to Top