Lazy choices in Django formIn a Django form, how do I make a field readonly (or disabled) so that it cannot be edited?What is a “slug” in Django?Does Django scale?How to prevent buttons from submitting formsHow to debug in Django, the good way?Django: Display Choice ValueHow to check Django versiondifferentiate null=True, blank=True in djangodjango userena editing form with related extra fieldsDjango - Cannot resolve keyword
Why does BezierFunction not follow BezierCurve at npts>4?
Does a bard know when a character uses their Bardic Inspiration?
Declaring a visitor to the UK as my "girlfriend" - effect on getting a Visitor visa?
C# TCP server/client class
Subverting the essence of fictional and/or religious entities; is it acceptable?
Has J.J.Jameson ever found out that Peter Parker is Spider-Man?
Skipping same old introductions
Approximating an expression for a potential
A wiild aanimal, a cardinal direction, or a place by the water
How was the cosmonaut of the Soviet moon mission supposed to get back in the return vehicle?
Can an unintentional murderer leave Ir Miklat for Shalosh Regalim?
Is there a word that describes people who are extraverted and/or energetic, but uneducated, unintelligent and/or uncreative?
Is it uncompelling to continue the story with lower stakes?
Speaker impedance: rewiring four 8 Ω speakers for use with 8 Ω amp output
How do people drown while wearing a life jacket?
What license to choose for my PhD thesis?
Confused over role of 「自分が」in this particular passage
Is this popular optical illusion made of a grey-scale image with coloured lines?
Is there any difference between "result in" and "end up with"?
How does shared_ptr<void> know which destructor to use?
coding the arrow's path in flowchart
Any information about the photo with Army Uniforms
How do I safety check that there is no light in Darkroom / Darkbag?
Is it moral to remove/hide certain parts of a photo, as a photographer?
Lazy choices in Django form
In a Django form, how do I make a field readonly (or disabled) so that it cannot be edited?What is a “slug” in Django?Does Django scale?How to prevent buttons from submitting formsHow to debug in Django, the good way?Django: Display Choice ValueHow to check Django versiondifferentiate null=True, blank=True in djangodjango userena editing form with related extra fieldsDjango - Cannot resolve keyword
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;
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!
python django forms lazy-evaluation
add a comment |
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!
python django forms lazy-evaluation
add a comment |
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!
python django forms lazy-evaluation
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!
python django forms lazy-evaluation
python django forms lazy-evaluation
edited Feb 20 '09 at 15:15
Eli Courtwright
129k57 gold badges197 silver badges249 bronze badges
129k57 gold badges197 silver badges249 bronze badges
asked Feb 20 '09 at 14:18
Tom VinerTom Viner
4,3875 gold badges32 silver badges37 bronze badges
4,3875 gold badges32 silver badges37 bronze badges
add a comment |
add a comment |
4 Answers
4
active
oldest
votes
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 !
2
Definitely the superior solution, this should be the accepted answer imo.
– Sverre Rabbelier
Feb 27 '11 at 16:17
2
/agree is the cleanest solution I have seen so far and this lets you skip problems with validations, an important difference from the ModelChoiceField.
– Hassek
Aug 18 '11 at 21:59
10
This does not appear to work, at least with Django 1.6, becauseChoiceField._set_choices
doesself._choices = self.widget.choices = list(value)
– spookylukey
Oct 23 '14 at 11:58
2
This does not work for me at all on Django 1.7, could anyone check if it works really? First, it raises Exception about the wrong type of returned value ("Lazy object returned unexpected type") when I use 'tuple' as 2nd parameter to 'lazy'. Second, when I use 'list' there, the function is called... once! Then it is not called any more and I have the same list of values as in the beginning.
– dotz
May 30 '15 at 17:33
add a comment |
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 :)
add a comment |
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.
add a comment |
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.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f569696%2flazy-choices-in-django-form%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
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 !
2
Definitely the superior solution, this should be the accepted answer imo.
– Sverre Rabbelier
Feb 27 '11 at 16:17
2
/agree is the cleanest solution I have seen so far and this lets you skip problems with validations, an important difference from the ModelChoiceField.
– Hassek
Aug 18 '11 at 21:59
10
This does not appear to work, at least with Django 1.6, becauseChoiceField._set_choices
doesself._choices = self.widget.choices = list(value)
– spookylukey
Oct 23 '14 at 11:58
2
This does not work for me at all on Django 1.7, could anyone check if it works really? First, it raises Exception about the wrong type of returned value ("Lazy object returned unexpected type") when I use 'tuple' as 2nd parameter to 'lazy'. Second, when I use 'list' there, the function is called... once! Then it is not called any more and I have the same list of values as in the beginning.
– dotz
May 30 '15 at 17:33
add a comment |
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 !
2
Definitely the superior solution, this should be the accepted answer imo.
– Sverre Rabbelier
Feb 27 '11 at 16:17
2
/agree is the cleanest solution I have seen so far and this lets you skip problems with validations, an important difference from the ModelChoiceField.
– Hassek
Aug 18 '11 at 21:59
10
This does not appear to work, at least with Django 1.6, becauseChoiceField._set_choices
doesself._choices = self.widget.choices = list(value)
– spookylukey
Oct 23 '14 at 11:58
2
This does not work for me at all on Django 1.7, could anyone check if it works really? First, it raises Exception about the wrong type of returned value ("Lazy object returned unexpected type") when I use 'tuple' as 2nd parameter to 'lazy'. Second, when I use 'list' there, the function is called... once! Then it is not called any more and I have the same list of values as in the beginning.
– dotz
May 30 '15 at 17:33
add a comment |
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 !
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 !
answered May 10 '09 at 11:21
SidiSidi
1,58613 silver badges15 bronze badges
1,58613 silver badges15 bronze badges
2
Definitely the superior solution, this should be the accepted answer imo.
– Sverre Rabbelier
Feb 27 '11 at 16:17
2
/agree is the cleanest solution I have seen so far and this lets you skip problems with validations, an important difference from the ModelChoiceField.
– Hassek
Aug 18 '11 at 21:59
10
This does not appear to work, at least with Django 1.6, becauseChoiceField._set_choices
doesself._choices = self.widget.choices = list(value)
– spookylukey
Oct 23 '14 at 11:58
2
This does not work for me at all on Django 1.7, could anyone check if it works really? First, it raises Exception about the wrong type of returned value ("Lazy object returned unexpected type") when I use 'tuple' as 2nd parameter to 'lazy'. Second, when I use 'list' there, the function is called... once! Then it is not called any more and I have the same list of values as in the beginning.
– dotz
May 30 '15 at 17:33
add a comment |
2
Definitely the superior solution, this should be the accepted answer imo.
– Sverre Rabbelier
Feb 27 '11 at 16:17
2
/agree is the cleanest solution I have seen so far and this lets you skip problems with validations, an important difference from the ModelChoiceField.
– Hassek
Aug 18 '11 at 21:59
10
This does not appear to work, at least with Django 1.6, becauseChoiceField._set_choices
doesself._choices = self.widget.choices = list(value)
– spookylukey
Oct 23 '14 at 11:58
2
This does not work for me at all on Django 1.7, could anyone check if it works really? First, it raises Exception about the wrong type of returned value ("Lazy object returned unexpected type") when I use 'tuple' as 2nd parameter to 'lazy'. Second, when I use 'list' there, the function is called... once! Then it is not called any more and I have the same list of values as in the beginning.
– dotz
May 30 '15 at 17:33
2
2
Definitely the superior solution, this should be the accepted answer imo.
– Sverre Rabbelier
Feb 27 '11 at 16:17
Definitely the superior solution, this should be the accepted answer imo.
– Sverre Rabbelier
Feb 27 '11 at 16:17
2
2
/agree is the cleanest solution I have seen so far and this lets you skip problems with validations, an important difference from the ModelChoiceField.
– Hassek
Aug 18 '11 at 21:59
/agree is the cleanest solution I have seen so far and this lets you skip problems with validations, an important difference from the ModelChoiceField.
– Hassek
Aug 18 '11 at 21:59
10
10
This does not appear to work, at least with Django 1.6, because
ChoiceField._set_choices
does self._choices = self.widget.choices = list(value)
– spookylukey
Oct 23 '14 at 11:58
This does not appear to work, at least with Django 1.6, because
ChoiceField._set_choices
does self._choices = self.widget.choices = list(value)
– spookylukey
Oct 23 '14 at 11:58
2
2
This does not work for me at all on Django 1.7, could anyone check if it works really? First, it raises Exception about the wrong type of returned value ("Lazy object returned unexpected type") when I use 'tuple' as 2nd parameter to 'lazy'. Second, when I use 'list' there, the function is called... once! Then it is not called any more and I have the same list of values as in the beginning.
– dotz
May 30 '15 at 17:33
This does not work for me at all on Django 1.7, could anyone check if it works really? First, it raises Exception about the wrong type of returned value ("Lazy object returned unexpected type") when I use 'tuple' as 2nd parameter to 'lazy'. Second, when I use 'list' there, the function is called... once! Then it is not called any more and I have the same list of values as in the beginning.
– dotz
May 30 '15 at 17:33
add a comment |
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 :)
add a comment |
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 :)
add a comment |
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 :)
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 :)
answered Feb 20 '09 at 14:33
Baishampayan GhoseBaishampayan Ghose
14.1k10 gold badges48 silver badges59 bronze badges
14.1k10 gold badges48 silver badges59 bronze badges
add a comment |
add a comment |
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.
add a comment |
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.
add a comment |
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.
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.
answered Apr 8 '15 at 14:32
JohnJohn
111 bronze badge
111 bronze badge
add a comment |
add a comment |
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.
add a comment |
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.
add a comment |
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.
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.
answered Mar 27 at 1:08
MrDBAMrDBA
3205 silver badges7 bronze badges
3205 silver badges7 bronze badges
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f569696%2flazy-choices-in-django-form%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown