Skip to main content
 首页 » 编程设计

python之Django 过滤器之按相关模型中字段的平均值过滤

2024年12月31日22mate10pro

我正在使用 django-filter 过滤我的 Festival 模型。还有另一种模型,Review,它包含有关节日的评论以及与Festival 模型相关的Foreignkey。 我的目标是能够通过 friendly 平均值 > 3 过滤节日(friendly 是一个字段,例如在 Review 模型中)。

知道怎么做吗?非常感谢 =]

模型.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(这是我的想法,我是 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 

请您参考如下方法:

像这样使用它:

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'))