Opened 7 years ago
Closed 7 years ago
#28311 closed New feature (wontfix)
Ability to specify field querysets in ModelForm constructor
Reported by: | Pascal Briet | Owned by: | nobody |
---|---|---|---|
Component: | Forms | Version: | 1.11 |
Severity: | Normal | Keywords: | modelform queryset |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Hi,
There is a common problematic I often encounter : Displaying a ModelForm with foreignkeys (ModelChoiceField) requiring sub-querysets.
e.g., I have a Restaurant
model, that I first create in a Country
(Restaurant::country
). Then, in a form, I want to specify a City
(Restaurant::city
).
I do not want to display all the cities from all the world, but only the cities from the pre-selected country. (please note that the subselection logic might be more complex in many cases).
Usually, you do the following in Django :
class RestaurantForm(forms.ModelForm): class Meta: model = Restaurant fields = ['name', 'city'] def __init__(self, *args, **kargs): super().__init__(*args, **kargs) self.fields['city'].queryset = City.objects.filter(country=self.fields['country']) my_form = RestaurantForm(instance=restaurant)
It works, but it looks to me rather complicated for such a common use (especially for beginners).
Would it be possible to pass through the Form contructor a dictionary of querysets that would replace the default ones ?
my_form = RestaurantForm(instance=restaurant, field_querysets={'city': City.objects.filter(country=restaurant.country)}
Does it make sense ? It doesn't invalidate the first approach. The classic way bounds the logic to the form itself - which is very handy - but I believe the suggested way would make Django more accessible to newbies.
Thanks,
I don't see a need to add an alternate way of doing this. In my opinion, it could lead to a slippery slope with proposals to add all sorts of all other form customization options in
ModelForm.__init__()
. Also, I feel the logic really does belong in the form, not in the view (or wherever the form is initialized).Feel free to propose the idea on the DevelopersMailingList if you disagree with my assessment.