Home > Technology > Custom Change Manipulators in Django(oldforms)

Custom Change Manipulators in Django(oldforms)

To tell you quite frankly, I never got to use an inbuilt manipulator while coding for Hackzor. I guess the primary reason being that my forms either had optional fields or i had to deal with two models at a time. I still could have avoided going custom, i guess i didn’t want to clutter the view with manipulation code.

So, on my path to custom manipulatorness, i missed this one HUGE turn called custom change manipulators. The docs didn’t say much about them and the comments weren’t too explicit either. After many hours of torturing unsuspecting victims on #Django, i finally found out that custom manipulators are really ‘custom’ – you’re responsible to storing the object and creating a dictionary for the form wrapper. It kinda sounds dumb right now, but it felt as hard the Da Vinci Code when i didn’t know the solution. So, in aid of all those poor, lost souls like me out there, Here’s how to make your own Custom Change Manipulator

The example i’m going to show you is naturally from Hackzor. I needed a custom change manipulator inorder to be able to put out a form where each contestant can edit his/her team details. List below, is the custom change manipulator that i wrote for the form:

class ChangeDetails (forms.Manipulator):
    ''' Change Membership details '''

    def __init__(self, user_id):
            self.original_object = User.objects.get(id=user_id)
        except User.DoesNotExist:
            from django.http import Http404
            raise Http404
        self.fields = (
                             length=20, maxlength=20,
                             length=20, maxlength=20,

    def isValidEmail (self, field_data, all_data):
        """ Checks if there is an already existing email and raises error if so"""
        except User.DoesNotExist:
        raise validators.ValidationError('The email "%s"
                                                 is already registered.' % field_data)

    def save(self, new_data):
        """ Saves The user object into the database
          with score set to 0 and is_active set to false"""
        self.original_object.first_name = new_data['first_name']
        self.original_object.last_name = new_data['last_name']
        self.original_object.email = new_data['email']
        print 'Saving UserProfile updation'
        return self.original_object

    def flatten_data(self):
        return {
                'username' : self.original_object.username,
                'email' : self.original_object.email,
                'first_name' : self.original_object.first_name,
                'last_name' : self.original_object.last_name,

Points where it differs from an add manipulator:
1. The __init__ function of my manipulator has an extra argument from which i get the primary key of the object to be changed and assign the object to self.original_object
2. save is implemented like in the custom add manipulator, expect that it meddles with the existing object rather than creating a new one.
3. flatten_data is the function that will return a dict of the variables that will eventually be passed to the formwrapper to be loaded on the page. I will be calling this function from my view

Now lets take a look at the view to complete the picture

def change_details(request):
    ''' Change details of existing users '''

    manipulator = ChangeDetails(request.user.id)

    if request.method == 'POST':
        new_data = request.POST.copy()
        print 'By post', new_data
        errors = manipulator.get_validation_errors(new_data)
        if not errors:
            new_user = manipulator.save(new_data)
            return render_to_response('simple_message.html',
                {'message' : 'Your Details have been updated'}, RequestContext(request))
            print 'Errors'
        errors = {}
        new_data = manipulator.flatten_data()
        print new_data
    form = forms.FormWrapper(manipulator, new_data, errors)
    return render_to_response('change_profile.html',
            {'form': form}, RequestContext(request))

    return render_to_response('register.html', {'form':form}, RequestContext(request))
Categories: Technology
  1. January 18, 2007 at 5:07 am

    Haczkor? Are you working on some project without me knowing? 😮

  2. January 18, 2007 at 6:11 am

    Doh! I can’t seem to get by without typos 😦
    Corrected anyway.

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: