[Django]-Passing data into django forms

9👍

This is a basic Python issue. You need to think about the order these commands are executed in, and their scope.

First, you define a form class called Test. That class has three attributes: a set_choices method, a get_choices method, and an options field. These definitions are evaluated when the class itself is defined. The definition of options calls get_choices(). However, there is no get_choices method in scope at that point, because the class is not yet defined.

Even if you somehow managed to sort out the scope issue, this would still not do what you want, because the definition of choices for options is done at define time. Even if you later call set_choices, options still has the value of get_choices that was returned when the field was defined.

So, what do you actually want to do? It seems like you want to set dynamic choices on the options field. So, you should override the __init__ method and define them there.

class Test(forms.Form):
    options = forms.ChoiceField(choices=())

    def __init__(self, *args, **kwargs):
        choices = kwargs.pop('choices', None)
        super(Test, self).__init__(*args, **kwargs)
        if choices is not None:
            self.fields['options'].choices = choices

0👍

Extending __init__ is a good way to add options to ChoiceField dynamically as Daniel Roseman explains in his answer.

Just to add to that … adding options at run time is hackish (at best). Here is the note about best practices (straight from Django ChoiceField documentation) –

Finally, note that choices can be any
iterable object — not necessarily a
list or tuple. This lets you construct
choices dynamically. But if you find
yourself hacking choices to be
dynamic, you’re probably better off
using a proper database table with a
ForeignKey. choices is meant for
static data that doesn’t change much,
if ever.

Leave a comment