Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/security/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 构建请求URL以按同一字段多次筛选Django queryset_Python_Django_Django Rest Framework_Django Q - Fatal编程技术网

Python 构建请求URL以按同一字段多次筛选Django queryset

Python 构建请求URL以按同一字段多次筛选Django queryset,python,django,django-rest-framework,django-q,Python,Django,Django Rest Framework,Django Q,我想使用Q多次过滤同一字段的Django queryset,以包括/排除该字段中具有特定值的记录 我将使用示例模型来说明我的案例。假设我有一个带有字段状态的记录模型。此字段可以是三种状态之一A,B,C class Record(models.Model): STATUS_A = 'A' STATUS_B = 'B' STATUS_C = 'C' SOME_STATUSES = ( (STATUS_A, 'Something A'),

我想使用
Q
多次过滤同一字段的Django queryset,以包括/排除该字段中具有特定值的记录

我将使用示例模型来说明我的案例。假设我有一个带有字段
状态的
记录
模型。此字段可以是三种状态之一
A
B
C

class Record(models.Model):
    STATUS_A = 'A'
    STATUS_B = 'B'
    STATUS_C = 'C'

    SOME_STATUSES = (
        (STATUS_A, 'Something A'),
        (STATUS_B, 'Something B'),
        (STATUS_C, 'Something C'),
    )

    status = models.CharField(
    max_length=1,
    choices= SOME_STATUSES,
    default= STATUS_A,
    )
我有一个
ViewSet
,负责返回
Record
对象的过滤查询集

现在,我正在按单个状态筛选查询集,因此我的
URL
看起来像:

.../?status=A
.../?status=B
.../?status=C
但假设我想按多个状态筛选queryset: 返回状态为
A
B
的所有记录。 或者,我想返回除状态为
C
之外的所有记录。我不确定在这种情况下如何构建URL。我知道在URL中复制参数是一种非常糟糕的做法:

.../?status=A&status=B
如何请求
A
B
C


问题的剩余部分是如何处理这些多个值还不清楚,可能是因为我不知道如何首先构建这样一个查询。

通过编写CustomdjangFilter,您可以实现这一点

示例代码

URL示例和用法

代码片段

views.py

from django_filters.rest_framework import DjangoFilterBackend
from .filters import CustomRecordFilter

class RecordViewSet(viewsets.ModelViewSet):
    queryset = Record.objects.all()
    serializer_class = RecordSerializer

    # django-filter-backend and custom-filter-class
    filter_backends = (DjangoFilterBackend, )
    filter_class = CustomRecordFilter
过滤器.py

import django_filters

class CustomRecordFilter(django_filters.FilterSet):
    status_exclude = django_filters.CharFilter(field_name='status', method='filter_status_exclude')
    status_include = django_filters.CharFilter(field_name='status', method='filter_status_include')

def filter_status_include(self, queryset, name, value):
    if not value:
        return queryset
    values = ''.join(value.split(' ')).split(',')
    queryset = queryset.filter(status__in=values)
    return queryset

def filter_status_exclude(self, queryset, name, value):
    if not value:
        return queryset
    values = ''.join(value.split(' ')).split(',')

    # exclude status
    queryset = queryset.exclude(status__in=values)
    return queryset

class Meta:
    model = UserRoleGroup
    fields = ('status', 'status_include', 'status_exclude')

您可以共享
ViewSet
代码吗?DRF对成员资格检查有一定的支持。@WillemVanOnsem它相当庞大,因为实际的视图集使用几个不同的参数过滤查询,而我正在使用几个mixin来使事情井然有序。我会尽量减少它,以适应一个问题,并在今天晚些时候上传它。但我的主要问题是如何构建这样的url。相关的:我认为您应该在querystring上发送一个
数组
,然后在后端进行过滤<代码>状态=[A、B、C]
。同时尝试使用django过滤器
/?status\u must=A,B&status\u mustnot=C
这是您期望的url吗?
import django_filters

class CustomRecordFilter(django_filters.FilterSet):
    status_exclude = django_filters.CharFilter(field_name='status', method='filter_status_exclude')
    status_include = django_filters.CharFilter(field_name='status', method='filter_status_include')

def filter_status_include(self, queryset, name, value):
    if not value:
        return queryset
    values = ''.join(value.split(' ')).split(',')
    queryset = queryset.filter(status__in=values)
    return queryset

def filter_status_exclude(self, queryset, name, value):
    if not value:
        return queryset
    values = ''.join(value.split(' ')).split(',')

    # exclude status
    queryset = queryset.exclude(status__in=values)
    return queryset

class Meta:
    model = UserRoleGroup
    fields = ('status', 'status_include', 'status_exclude')