Hej! :)
I want to filter my data before I do some calculations with it with an AND operator. The chosen filter fields should ALL be applied. I added some fields of the mode to the filter function and I can filter (e.g.) for the name and the year seperate. But not combined. If I try to filter for both name AND year at the same time I would just get the results from year.
In my model I got an M2M to another model in which the year is set:
# models.py
class Plant(models.Model):
name = models.CharField(
max_length=200
)
used_xducts = models.ManyToManyField(
Xduct,
through="UsedXduct",
blank=True,
related_name="used_in_plant"
)
class UsedXduct(models.Model):
plant = models.ForeignKey(
Plant,
on_delete=models.PROTECT,
related_name="used_in_plant"
)
xduct = models.ForeignKey(
Xduct,
on_delete=models.PROTECT,
related_name="xduct"
)
year = models.SmallIntegerField(
validators=[validate_year],
blank=True,
null=True
)
class Xduct(models.Model):
code = models.CharField(
max_length = 20,
blank = True,
null = True,
unique = True
)
name_english = models.CharField(
max_length = 200,
blank = True,
null = True,
unique = True
)
description_english = models.TextField(
max_length = 500,
blank = True
)
explanation_english = models.TextField(
max_length = 4000,
blank = True
)
# filters.py
class PlantsNameFilter(django_filters.FilterSet):
name = ModelChoiceFilter(queryset=Plant.objects.all())
year = django_filters.NumberFilter(method='year_filter', label='Year')
class Meta:
model = Plant
fields =["name", "year"]
def year_filter(self, queryset, name, value):
return Plant.objects.filter(
Q(used_in_plant__year=value)
)
Does anyone have an idea on whats going wrong? I have a similar filter for something else and it's working fine. I seem to miss something important.
Any help is appreciated! Thanks for the time :)
CodePudding user response:
I think you need to use the queryset
in the method year_filter
of your filter. Currently you create a fresh queryset from scratch if the year-filter is applied. Replace Plant.objects
with queryset
like below:
class PlantsNameFilter(django_filters.FilterSet):
name = ModelChoiceFilter(queryset=Plant.objects.all())
year = django_filters.NumberFilter(method='year_filter', label='Year')
class Meta:
model = Plant
fields =["name", "year"]
def year_filter(self, queryset, name, value):
return queryset.filter( # <---- HERE
Q(used_in_plant__year=value)
)