Reputation: 59
I'm using django-filter to filter through my Festival
model. There is another model, Review
, which contains reviews about festivals and related to the Festival
model by a Foreignkey
.
My goal is to be able to filter festivals by friendly
average > 3 (friendly
is a one field for example in Review
model).
Any idea how to do it? Many thanks =]
Models.py
class Review(models.Model):
...
festival = models.ForeignKey(
Festival,
related_name='Festival_Reviews',
on_delete=models.CASCADE,
null=True,
blank = True,
default = '',
)
score_choices = (
(1, 'Bad'),
(2, 'Okay'),
(3, 'Good'),
(4, 'Great'),
(5, 'Superb'),
)
friendly = models.IntegerField(
choices=score_choices,
default='',
null=True,
blank = True,
)
class Festival(models.Model):
...
created_at = models.DateTimeField(auto_now=True)
name = models.CharField(max_length=200)
Filter.py (this was my idea, I'm pretty new to Django)
class FestivalFilter(django_filters.FilterSet):
...
Festival_Reviews_friendly = django_filters.BooleanFilter(field_name='Festival_Reviews',method='avg_above3')
def avg_above3(self, queryset, name, value):
return queryset.aggregate(friendly_avg=Avg('friendly')).filter(friendly_avg__gt=3)
Views.py
class HomePage(ListFilteredMixin, AjaxListView):
template_name = 'index.html'
page_template = 'index_page.html'
model = models.Festival
paginate_by = 12
context_object_name = 'festivals'
filter_set = FestivalFilter
Upvotes: 2
Views: 1261
Reputation: 51988
Use it like this:
class FestivalFilter(django_filters.FilterSet):
festival_friendly_review = django_filters.BooleanFilter(field_name='Festival_Reviews',method='avg_above3')
class Meta:
model = Festival
fields = ['festival_friendly_review']
def avg_above3(self, queryset, name, value):
return queryset.annotate(friendly_avg=Avg('Festival_Reviews__friendly')).filter(friendly_avg__gt=3) # use annotate instead of aggregate
filter = FestivalFilter({festival_friendly_review:True}, Festival.objects.all())
print(filter.qs)
print(filter.qs.values('friendly_avg'))
Upvotes: 2