I have a Django my_forms.py like this:
class CarSearchForm(forms.Form): # lots of fields like this bodystyle = forms.ChoiceField(choices=bodystyle_choices())
Each choice is e.g. ("Saloon", "Saloon (15 cars)"). So the choices are computed by this function.
def bodystyle_choices(): return [(bodystyle.bodystyle_name, '%s (%s cars)' % (bodystyle.bodystyle_name, bodystyle.car_set.count())) for bodystyle in Bodystyle.objects.all()]
My problem is the choices functions are getting executed every time I merely import my_forms.py. I think this is due to the way Django declares its fields: in the class but not in a class method. Which is fine but my views.py imports my_forms.py so the choices lookups are done on every request no matter which view is used.
I thought that maybe putting choices=bodystyle_choices with no bracket would work, but I get:
'function' object is not iterable
Obviously I can use caching and put the "import my_forms" just in the view functions required but that doesn't change the main point: my choices need to be lazy!
Set the exclude attribute of the ModelForm 's inner Meta class to a list of fields to be excluded from the form.
The disabled boolean argument, when set to True , disables a form field using the disabled HTML attribute so that it won't be editable by users. Even if a user tampers with the field's value submitted to the server, it will be ignored in favor of the value from the form's initial data.
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 !
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 :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With