Django TypeError:通过外键过滤时无法过滤非条件表达式

问题描述 投票:0回答:1

我翻阅了多个类似的问题,但找不到逻辑,我的操作不成功。

我有一个论坛应用程序,其结构是“论坛->子论坛->主题->评论”,对应子论坛、主题和评论的模型。我必须在每个子论坛页面上实现一个过滤器(其中显示相应主题的列表),通过它我可以通过多种条件配置主题之间的搜索。

特别是我必须实现一个自定义过滤器,我的想法是为空主题创建一个过滤器,即仅包含初始评论且没有回复的主题。经过绝望的挣扎,我终于明白了如何在查询集中实现反向外键连接,但现在我不能使用查询集表达式作为过滤器,因为它返回 TypeError: Cannot filter against a non-conditional expression.

具体内容如下:

过滤器.py:

import django_filters
from django.db.models import Count

from forum.models import Topic


class TopicFilter(django_filters.FilterSet):
    date_span = django_filters.DateRangeFilter(field_name='created', label='Период создания')
    comments = django_filters.CharFilter(field_name='comment__content', lookup_expr='icontains', label='Комментарии')
    subject = django_filters.CharFilter(lookup_expr='icontains', label='Тема обсуждения')
    creator = django_filters.CharFilter(field_name='creator__username', lookup_expr='icontains', label='Создатель темы')
    is_empty = django_filters.BooleanFilter(method='filter_empty', label='Темы без комментариев')

    class Meta:
        model = Topic
        fields = ['subject', 'creator', 'date_span', 'comments', 'is_empty']

    def filter_empty(self, queryset, value):
        comment_count_gte_1 = Topic.objects.annotate(comment_count=Count('comments')).filter(comment_count__gte=1)
        comment_count_lt_1 = Topic.objects.annotate(comment_count=Count('comments')).filter(comment_count__lt=1)
        if value is True:
            return queryset.filter(comment_count_lt_1)
        elif value is False:
            return queryset.filter(comment_count_gte_1)
        else:
            return queryset

上述方法不起作用 - 显然,无法提供查询集表达式的链接作为过滤条件。但即使输入表达式本身,那就是:

def filter_empty(self, queryset, value):
        if value is True:
            return queryset.filter(Topic.objects.annotate(comment_count=Count('comments')).filter(comment_count__lt=1))
        elif value is False:
            return queryset.filter(Topic.objects.annotate(comment_count=Count('comments')).filter(comment_count__gte=1))
        else:
            return queryset

那么它也不起作用。

比较一下:

def filter_empty(self, queryset, value):
        comment_count = Topic.objects.annotate(comment_count=Count('comments'))

        if value is True:
            return queryset.filter(comment_count < 1)
        elif value is False:
            return queryset.filter(comment_count >= 1)
        else:
            return queryset

返回了另一个错误:TypeError:'QuerySet'和'int'的实例之间不支持'>='

现在我很难为潜在的查询集制定适当的过滤器表达式。因此我来这里寻求帮助和建议。

如果需要任何其他信息/文件,我准备提供。

python django
1个回答
0
投票

.filter(…)
 [Django-doc]
.annotate(…)
 [Django-doc]
上使用:

def filter_empty(self, queryset, value):
    queryset = Topic.objects.annotate(comment_count=Count('comments'))

    if value is True:
        return queryset.filter(comment_count__lt=1)
    elif value is False:
        return queryset.filter(comment_count__gte=2)
    else:
        return queryset
© www.soinside.com 2019 - 2024. All rights reserved.