Login

Form and FormSet that are defined dynamically with request-data

Author:
Lacour
Posted:
January 10, 2010
Language:
Python
Version:
1.1
Score:
2 (after 2 ratings)

This is how you can access the user's request in the Form or FormSet definition, e.g. to define the choices of a ChoiceField dynamically. Either you use it for a single Form or a whole FormSet, just pass the view's request into the Form or FormSet instantiation.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
Forms.py:
    from django import forms
    from django.forms.formsets import BaseFormSet, formset_factory
    class RequestFormSet(BaseFormSet):
        """
        Formset that passes the HttpRequest on to every Form's __init__
        Suitable to populate Fields dynamically depending on request
        """
        def __init__(self, *args, **kwargs):
            self.request = kwargs.pop('request', None)
            super(RequestFormSet, self).__init__(*args, **kwargs)  #this calls _construct_forms()

        def _construct_forms(self): #this one is merely taken from django's BaseFormSet
            # except the additional request parameter for the Form-constructor
            self.forms = []
            for i in xrange(self.total_form_count()):
            self.forms.append(self._construct_form(i, request=self.request))

    class MyForm(forms.Form):
        my_choice_field = forms.ChoiceField() # choices will be created dynamically
        def __init__(self, *args, **kwargs):
            request = kwargs.pop('request', None)
            super(MyFormForm, self).__init__(*args, **kwargs)
            # the rest is just an example that looks up the LANGUAGE_CODE,
            # pulls the right translation from the database and creates
            # my_choice_field's choices from it. You can do here whatever you want with request
            if request:
                LANG = request.LANGUAGE_CODE #needs LocaleMiddelware or raises AttributeError
                self.fields['my_choice_field'].choices = zip(
                    [x.number for x in MyModel.objects.all()],
                    [x.locale.get(language__iexact=LANG).name for x in MyModel.objects.all()]
                )

    MyFormSet = formset_factory(MyForm, formset=RequestFormSet)

Views.py:
    my_view(request):    
        # ...
        formset = MyFormSet(request=request)
        form = MyForm(request=request)
        # ...

More like this

  1. Template tag - list punctuation for a list of items by shapiromatron 11 months, 2 weeks ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 11 months, 3 weeks ago
  3. Serializer factory with Django Rest Framework by julio 1 year, 6 months ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 7 months ago
  5. Help text hyperlinks by sa2812 1 year, 8 months ago

Comments

jnns (on September 29, 2010):

Thank you very much. I was twisting my head with this one.

#

Please login first before commenting.