[Django]-Lazy choices in Django form

51๐Ÿ‘

โœ…

You can use the โ€œlazyโ€ function ๐Ÿ™‚

from django.utils.functional import lazy

class CarSearchForm(forms.Form):  
    # lots of fields like this
    bodystyle = forms.ChoiceField(choices=lazy(bodystyle_choices, tuple)())

very nice util function !

๐Ÿ‘คSidi

18๐Ÿ‘

Try using a ModelChoiceField instead of a simple ChoiceField. I think you will be able to achieve what you want by tweaking your models a bit. Take a look at the docs for more.

I would also add that ModelChoiceFields are lazy by default ๐Ÿ™‚

2๐Ÿ‘

You can now just use (since I think Django 1.8):

class CarSearchForm(forms.Form):  
    # lots of fields like this
    bodystyle = forms.ChoiceField(choices=bodystyle_choices)  

Note the missing parenthesis. If you need to pass arguments, I just make a special version of the function with them hardcoded just for that form.

๐Ÿ‘คMrDBA

1๐Ÿ‘

Expanding on what Baishampayan Ghose said, this should probably be considered the most direct approach:

from django.forms import ModelChoiceField

class BodystyleChoiceField(ModelChoiceField):
    def label_from_instance(self, obj):
        return '%s (%s cars)' % (obj.bodystyle_name, obj.car_set.count()))

class CarSearchForm(forms.Form):  
    bodystyle = BodystyleChoiceField(queryset=Bodystyle.objects.all())

Docs are here: https://docs.djangoproject.com/en/1.8/ref/forms/fields/#modelchoicefield

This has the benefit that form.cleaned_data['bodystyle'] is a Bodystyle instance instead of a string.

๐Ÿ‘คJohn

Leave a comment