Unable to add a field to a model using a filter
anthonygoslar opened this issue · 1 comments
anthonygoslar commented
I have a model called RealEstate. It has a number of fields I want dynamic choices and filter methods for. Because the ModelChoiceFilter and ModelMultipleChoiceFilter don't allow for a method on the filter, I have used a ChoiceFilter and MultipleChoiceFilter instead and have defined the choices form a Queryset.
This seems to have caused some issues:
- It doesn't dynamically update the field choices unless I call the method after init. It took me a while to figure out that these initialize when the server starts.
- I can't add model fields if I initiate the choices with my Queryset as it throws an error on makemigrations that the new model field is not found.
I suspect that I'm probably using the wrong field for the job but thought that I should raise it and share my solution by only calling the choices Queryset after the super().init(*args, **kwargs) in init. Here's an example below:
def destination_country_choices() -> tuple:
options = []
for obj in RegionOption.objects.filter(show=True).order_by("order"): # This queryset is causing the issue
options.append((obj.lookup_name, obj.name))
return tuple(options)
class PublishedDealListFilter(django_filters.FilterSet):
destination_country = django_filters.ChoiceFilter(
field_name="destination__region__country",
label="Select a country",
empty_label="All countries",
choices=tuple(), # choices are set in __init__
method="filter_destination_country",
)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.form.fields["destination_country"].choices = destination_country_choices()
def filter_destination_country(self, queryset, destination_country, value):
if value or value != "":
return queryset.filter(
Q(destination__region__country=value)
| Q(destination__region__name=value)
)
return queryset
Thanks
carltongibson commented
Yes, this is right. Dynamically setting choices should be done in __init__
as you've found.