I have a django ModelChoiceField that won't validate if I override the queryset.
class PersonalNote(forms.Form):
tile = ModelChoiceField(queryset=Tile.objects.none())
note = forms.CharField()
form = PersonalNote()
form.fields['tile'].queryset = Tile.objects.filter(section__xxx=yyy)
The form.is_valid()
error is: "Select a valid choice. That choice is not one of the available choices".
If Tile.objects.none()
is replaced with Tile.objects.all()
it validates, but loads far too much data from the database. I've also tried:
class PersonalNote(forms.Form):
tile = ModelChoiceField(queryset=Tile.objects.none())
note = forms.CharField()
def __init__(self, *args, **kwargs):
yyy = kwargs.pop('yyy', None)
super(PersonalNote, self).__init__(*args, **kwargs)
if yyy:
self.fields['tile'].queryset = Tile.objects.filter(section__xxx=yyy)
What might be wrong here? Note the real application also overrides the label, but that does not seem to be a factor here:
class ModelChoiceField2(forms.ModelChoiceField):
def label_from_instance(self, obj):
assert isinstance(obj,Tile)
return obj.child_title()
I also had this problem. The idea is to dynamically change the queryset of a
ModelChoiceField
based on a condition (in my case it was a filter made by anotherModelChoiceField
).So, having the next model as example:
As you can see,
MyModel
has a foreign key withFooModel
, but not withFilterModel
. So, in order to filter theFooModel
options, I added a newModelChoiceField
on my form:Then, on your Front-End you can use Ajax to load the options of
foo_field
, based on the selected value ofmy_filter_field
. At this point everyting should be working. But, when the form is loaded, it will bring all the posible options fromFooModel
. To avoid this, you need to dynamically change the queryset offoo_field
.On my form view, I passed a new argument to
MyForm
:Now, you can use that argument on
MyForm
to change the queryset:After 2 hours I found the solution. Because you specified a queryset of none in the class definition, when you instantiate that PersonalNote(request.POST) to be validated it is referenceing a null query set
To fix this, when you create your form based on a POST request be sure to overwrite your queryset AGAIN before you check is_valid()
When you pass an empty queryset to
ModelChoiceField
you're saying that nothing will be valid for that field. Perhaps you could filter the queryset so there aren't too many options.