Wednesday, April 3, 2013

Incorporating request variable in django forms dynamically

In some cases, you may need to change form contents according to the user's session information. Just like I'd like to display the content for a specific DJANGO_SITE in one of the fields: categories. User should see only the categories of the site he belongs to. There should be a filtering but we can't use request data in Forms! One way is like I explained before. But this requires the form to be called with additional parameters. What if you can't modify those parameters because the view calling it is a third-party module? Then you may wrap the form in a function and create a new form definition according to the request with the session info in it:

def get_edit_profile_form(request):
    class EditProfileForm(BaseEdit):
        def __init__(self, *args, **kw):
            super(BaseEdit, self).__init__(*args, **kw)
            self.fields['categories'].queryset = Category.objects.filter(site=request.site)


def my_profile_edit(request, username):
    # do anything before performing the original profile edit
    response = userena_views.profile_edit(request, username=username, edit_profile_form=get_edit_profile_form(request))
    # do anything after performing the original profile edit.
    return response

This way we don't have to modify userena which is a third party module.