Well, I'm stuck in that problem for quite long now. Went to read some question / answers and blog, and at this point I don't understand why this is not working.
I'm gonna make my example as simple as possible.
Let's say I have a ModelMultipleChoiceField :
myfield = ModelMultipleChoiceField(
queryset=SomeObject.objects.none(),
label='',
widget=forms.CheckboxSelectMultiple(
attrs={
'class': 'mtlz-checkbox-group',
'label': 'some label: '
}
),
required=False
)
I set my queryset to none cause I need to compute the result dynamically. Note that this is in a ModelForm and that this field is a field of my object that I needed to custom (with some custom widget).
Well now i'm changing the queryset in the __init__()
method :
def __init__(self, *args, **kwargs):
super(EquipeForm, self).__init__(*args, **kwargs)
self.base_fields['myfield'].queryset = self.method()
Here self.method()
is a method that's computing my queryset, and it's working fine. So, whatever, the choices were not getting updated except when I refresh (just pressing f5, not cache and stuff). Continuing my reading, I read that self.base_fields['myfield'].widget.choices
were cached and so I had to force the "refresh" too in my init :
def __init__(self, *args, **kwargs):
super(EquipeForm, self).__init__(*args, **kwargs)
self.base_fields['myfield'].queryset = self.method()
self.base_fields['myfield'].widget.choices = self.base_fields['myfield'].choices
Using a pdb, I saw the choices were updated, and looks like the widget choices too. But still, when I first come on my form, the last choices are displayed and seemed to be cache. If I just press f5, again, it's now the right choices displayed.
In a last try I declared the all field in the __init__()
method but it's just the same.
So what am I missing? Is there any other cache involved as my choices seem to change in my __init__()
but are always one turn late ? Does that come from my custom widget (which herit from a normal widget) ?
For information, it's on django 1.11.
EDIT: the self.method()
:
def method(self):
ids = []
if not self.instance.attribute:
for obj in SomeObject.objects.exclude(id=self.instance.id):
ids += obj.members.all().filter(
some_condiftion=False
).values_list('id', flat=True)
return SomeOtherObject.objects.filter(is_superuser=False) \
.exclude(id__in=ids).order_by('name')
SomeObject.members
is a manytomany fields related to SomeOtherObject
. That's why I have a ModelMultipleChoiceField
.
Thanks in advance for your help
The problem is that you are updating self.base_fields
, which is the fields dict of the class , rather than self.fields
, which is the copy on the instance.
Since fields
is already created by the time you update base_fields
, it uses the old version of the choices; the next time you render the page, it will use the version created this time.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.