简体   繁体   中英

Django ModelChoiceField choices not updating

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM