I want a ModelForm
to have limited options for a foreign key, depending on another value on the form.
It looks like the following code, based roughly on this StackOverflow answer, would do what I want, except update the foreign key options when the value changes. At least, that’s what the comments on the answer suggest, and it would make sense, because it only seems to set the QuerySet
when the form is instantiated:
from django import forms
from django.contrib import admin
from models import *
class SupplierAdminForm(forms.ModelForm):
class Meta:
model = Supplier
fields = "__all__"
def __init__(self, *args, **kwargs):
super(SupplierAdminForm, self).__init__(*args, **kwargs)
if self.instance and self.instance.dog:
self.fields['cat'].queryset = Cat.objects.filter(liked_dogs=self.instance.dog)
else:
self.fields['cat'].queryset = Cat.objects.none()
class SupplierAdmin(admin.ModelAdmin):
form = SupplierAdminForm
I suppose the form would need to have some AJAX code to fetch a new queryset, each time the dog
value changes in the above example. I’m not sure if that’s within the scope of Django’s forms.
In an ideal world, if I added a constraint to the model, the form would automatically include this. But again, I don’t know whether this functionality exists. And for my purposes, a base form that does what I want, that I could code different subclasses from (e.g. for the admin tool and for the user-facing site), would already be marvellous.
I basically just want to avoid writing unnecessary code to reinvent the wheel for what seems a reasonably common use case. So, does this kind of functionality exist, either in stock Django, or in a reputable third-party library?
I’m sorry if this is already answered in this forum. I’ve browsed the posts in this forum about Passing an altered queryset to ModelChoiceField and altering queryset in a field of generic CreateView form, but they honestly go a bit over my head and I’m not sure they do what I want. Maybe this post essentially boils down to the same thing, but it has no answers yet.