Getting dynamic model choices in newforms

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
from django import newforms as forms
from models import Language

# I put this on all required fields, because it's easier to pick up
# on them with CSS or JavaScript if they have a class of "required"
# in the HTML. Your mileage may vary.
attrs_dict = { 'class': 'required' }

class AddSnippetForm(forms.Form):
    """
    Form used for adding Snippets.
    
    """
    def __init__(self, *args, **kwargs):
        super(AddSnippetForm, self).__init__(*args, **kwargs)
        self.fields['language'].choices = [('', '----------')] + [(lang.id, lang.name) for lang in Language.objects.all()]
    
    title = forms.CharField(max_length=250, widget=forms.TextInput(attrs=attrs_dict))
    description = forms.CharField(widget=forms.Textarea(attrs=attrs_dict))
    code = forms.CharField(widget=forms.Textarea(attrs=attrs_dict))
    tag_list = forms.CharField(max_length=250, widget=forms.TextInput(attrs=attrs_dict))
    language = forms.ChoiceField(choices=(), widget=forms.Select(attrs=attrs_dict))

Comments

dschein (on March 1, 2007):

It is also easy to create a builder function. You can use the same caching mechanism you do with other functions and even return different forms depending on the arguments.

@memoize_to_cache
def schedule_form(schedule, category):
    def _get_subjects():
        # some time consuming returns your choices
        # ...

    if category == CR:
        class CreditCourseSearchForm (forms.Form):
            subjects = forms.MultipleChoiceField(_get_subjects(), required=False)
            advising_codes = forms.ChoiceField(ADVISING_CODE_CHOICES, required=False)
            # ... 
        return CreditCourseSearchForm
    else:
        class NonCreditCourseSearchForm (forms.Form):
            subjects = forms.MultipleChoiceField(_get_subjects(), required=False)
            learning_community = forms.MultipleChoiceField(COMMUNITIES, required=False)
            # ... 
        return CreditCourseSearchForm

#

wub (on July 23, 2007):

Thank you!!!

I have spent several days trying to figure out how to filter a lookup table based on a value passed at run time. I was on the verge of deciding it could not be done, when I discovered this Snippet.

My only wish now is that I could understand >why< this works, when nothing else I tried did, but fortunately many things that I do not understand work anyway.

#

max (on July 25, 2007):

Thank you for this snippet, one more question:

after

self.fields['language'].choices =

i put

'myfunction()'

, returning a list of choices and between '' because it is defined in another python file.

i got the following error at execution time:

need more than 1 value to unpack

What does it mean ???

Thank you very much

max

#

ben_eliott (on May 8, 2008):

Thank you for this helpful snippet ubernostrum.

If the form is bound and you want to filter the database query based on a value therein you can access it by: self.data.get('fieldname')

#

(Forgotten your password?)

You may use Markdown syntax here, but raw HTML will be removed.