Django rest框架自定义过滤器后端数据复制

2024-10-05 10:01:03 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试使我的自定义过滤器和订购后端与django rest框架中的默认搜索后端一起工作。过滤和排序相互配合得很好,但是当查询中包含了搜索,并且我试图按对象名对查询排序时,就会发生数据重复。在

我试图打印查询和查询大小,但当我将其记录在过滤器中时似乎没问题,但在一个响应中,我有不同的对象计数(例如,过滤器查询中有79个对象,最终结果中有170个重复对象)

这是我的filterset类

class PhonesFilterSet(rest_filters.FilterSet):
    brands = InListFilter(field_name='brand__id')
    os_ids = InListFilter(field_name='versions__os')
    version_ids = InListFilter(field_name='versions')
    launched_year_gte = rest_filters.NumberFilter(field_name='phone_launched_date__year', lookup_expr='gte')
    ram_gte = rest_filters.NumberFilter(field_name='internal_memories__value', method='get_rams')
    ram_memory_unit = rest_filters.NumberFilter(field_name='internal_memories__units', method='get_ram_units')

    def get_rams(self, queryset, name, value):
        #here is the problem filter
        #that not works with ordering by name
        q=queryset.filter(Q(internal_memories__memory_type=1) & Q(internal_memories__value__gte=value))
        print('filter_set', len(q))
        print('filter_set_query', q.query)
        return q


    def get_ram_units(self, queryset, name, value):
        return queryset.filter(Q(internal_memories__memory_type=1) & Q(internal_memories__units=value))


    class Meta:
        model = Phone
        fields = ['brands', 'os_ids', 'version_ids', 'status', 'ram_gte']

我的订购课程:

^{pr2}$

视图集类:

class PhoneViewSet(viewsets.ModelViewSet):
    queryset = Phone.objects.all()
    serializer_class = PhoneSerializer
    filter_backends = (filters.SearchFilter, CustomFilterBackend, django_filters.rest_framework.DjangoFilterBackend)
    search_fields = ('brand__name', 'model__name')
    ordering_fields = ('brand__name', 'model__name')
    filter_class = PhonesFilterSet

因此,当我使用filter和search应用排序时,我不希望数据重复。我的问题是,为什么过滤器和响应中的对象数量不同,数据会被复制?我不知道从这里开始调试。提前谢谢。在


Tags: 对象namerestids过滤器fieldvaluefilter
1条回答
网友
1楼 · 发布于 2024-10-05 10:01:03

{cd1>使用此修复程序:

Returns a new QuerySet that uses SELECT DISTINCT in its SQL query. This eliminates duplicate rows from the query results.

By default, a QuerySet will not eliminate duplicate rows. In practice, this is rarely a problem, because simple queries such as Blog.objects.all() don’t introduce the possibility of duplicate result rows. However, if your query spans multiple tables, it’s possible to get duplicate results when a QuerySet is evaluated. That’s when you’d use distinct().

但是请注意,您仍然可能得到重复的结果:

Any fields used in an order_by() call are included in the SQL SELECT columns. This can sometimes lead to unexpected results when used in conjunction with distinct(). If you order by fields from a related model, those fields will be added to the selected columns and they may make otherwise duplicate rows appear to be distinct. Since the extra columns don’t appear in the returned results (they are only there to support ordering), it sometimes looks like non-distinct results are being returned.

https://docs.djangoproject.com/en/2.2/ref/models/querysets/#django.db.models.query.QuerySet.distinct

{sql{如果您可以使用cd2}来指定哪些字段是

所以,我将return queryset.distinct()在你评论你得到问题的方法中。我不会总是应用它(正如我在上面的调试注释中写的那样),因为简单的查询不需要它。在

相关问题 更多 >

    热门问题