如果查询参数错误,如何停止django REST框架以显示所有记录
我使用Django REST框架,并使用过滤器过滤查询集 像这样如果查询参数错误,如何停止django REST框架以显示所有记录,django,django-rest-framework,Django,Django Rest Framework,我使用Django REST框架,并使用过滤器过滤查询集 像这样 http://example.com/api/products/4675/?category=clothing&max_price=10.00 但是我已经看到,如果过滤器中有错误或者查询参数不存在,那么它会显示所有结果,这是非常糟糕的 如果查询参数有问题,我宁愿不要结果,因为有时我不知道这是否有效 编辑 这是我的密码 class userFilter(django_filters.FilterSet): strict =
http://example.com/api/products/4675/?category=clothing&max_price=10.00
但是我已经看到,如果过滤器中有错误或者查询参数不存在,那么它会显示所有结果,这是非常糟糕的
如果查询参数有问题,我宁愿不要结果,因为有时我不知道这是否有效
编辑
这是我的密码
class userFilter(django_filters.FilterSet):
strict = True
class Meta:
model = User
fields = ('is_active', 'is_archived', 'age')
休息
这是REST设置
REST_FRAMEWORK = {
'DEFAULT_MODEL_SERIALIZER_CLASS':
'rest_framework.serializers.HyperlinkedModelSerializer',
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
],
'DEFAULT_FILTER_BACKENDS': (
'rest_framework.filters.DjangoFilterBackend',
'rest_framework.filters.SearchFilter',
'rest_framework.filters.OrderingFilter',
),
# 'PAGINATE_BY': 1,
'PAGINATE_BY_PARAM': 'page_size',
'MAX_PAGINATE_BY': 100,
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.BasicAuthentication',
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.TokenAuthentication',
)
}
如果您正在使用,请查看
strict选项控制当发生错误时是否返回结果
用户为任何筛选器字段指定的值无效。通过
默认情况下,strict设置为True,这意味着空查询集为
如果任何字段包含无效值,则返回。你可以松开这个
将strict设置为False将有效忽略
筛选字段(如果其值无效)
过滤器:
from django_filters.filterset import FilterSet
class UserFilter(FilterSet):
strict = True
class Meta:
model = User
fields = ['username']
设置:(假设您已安装)
现在,如果有人这样做:
http://api.example.com/users/?username=myuser&badfilter=1
…它将返回一个空列表,因为badfilter
不存在
由于自动默认为
strict=True
,我感觉您没有利用DjangoFilterBackend
标记的答案对我不起作用。我通过重写“get”方法解决了这个问题:
您的具体问题源于您在GET查询中调用的参数没有在
UserFilter
中定义。因此,DRF仅考虑以下参数:
fields = ('is_active', 'is_archived', 'age')
此外,strict
仅控制查询参数的值,如果参数本身存在则不控制。比如说
GET mydomain.com/resource_path?whatever=blabla
返回整个queryset,在我看来这是错误的,至少不符合REST
最后,我编写了一个小方法来手动检查请求中传递的查询参数是否确实存在。,strict
只过滤分配给查询参数的值,而不过滤查询参数的存在
否则,像分页这样添加自己的查询参数的事情会破坏API
您可以覆盖get\u queryset()
以验证查询键:
class List(generics.ListAPIView):
queryset = MyModel.objects.all()
serializer_class = MyModelSerializer
filter_fields = ('q1', 'q2',)
# or filter_class
def get_queryset(self):
paging = set(['limit', 'offset'])
qs = super(RestrictedQueryMixin, self).get_queryset()
# Optional mutual exclusion check below...
if hasattr(self, 'filter_fields') and hasattr(self, 'filter_class'):
raise RuntimeError("%s has both filter_fields and filter_class" % self)
if hasattr(self, 'filter_class'):
filter_class = getattr(self, 'filter_class', None)
filters = set(filter_class.get_filters().keys())
elif hasattr(self, 'filter_fields'):
filters = set(getattr(self, 'filter_fields', []))
else:
filters = set()
for key in self.request.GET.keys():
if key in paging:
continue
if key not in filters:
return qs.none()
return qs
我把它做成了一个调味品
或者,您可以提出
rest\u framework.exceptions.APIException
。您也可以从self.paginator.get\u schema\u fields(self)
动态获取分页器字段。我是通过在继承泛型的类中重载函数get\u queryset()来实现这一点的。您可以使用self.request.query\u参数检查参数,并为任何情况编写自定义处理程序。您应该发布代码。。看了以后就明白了。。如果你真的在关注你提到的链接。。当它返回一个初始化为objects.all的queryset时,它将给出所有结果,而应该检查查询参数,如果不正确,则返回None。。为了得到更好的答案,请说出你的代码@vijayshanker嗨vijay我已经添加了代码。请使用lookoverride get\u queryset方法。。并在请求中查找查询参数以缩小结果范围。。这应该可以看看这个:@Michale,我试过了,它仍然会显示所有的记录。我认为应该设置REST而不是过滤器。您能检查一下吗?我需要从您的设置文件中查看您的REST\u FRAMEWORK
设置。很抱歉延迟回复。我已添加我的REST设置。请看一看。我被困在同一个案子里。对于使用ModelViewSet而不是泛型的用户,请记住您应该覆盖list
,而不是get
。问题是,在这种情况下,您还需要覆盖其他方法(操作)(检索、更新等):(我更喜欢覆盖get_queryset(个人偏好)。这个答案非常重要--strict
只控制值!请注意,如果您使用django rest swagger,则需要将“格式”添加到忽略的键列表中。有趣的是,您应该提到这一点--我前几天不得不这么做!
fields = ('is_active', 'is_archived', 'age')
GET mydomain.com/resource_path?whatever=blabla
class List(generics.ListAPIView):
queryset = MyModel.objects.all()
serializer_class = MyModelSerializer
filter_fields = ('q1', 'q2',)
# or filter_class
def get_queryset(self):
paging = set(['limit', 'offset'])
qs = super(RestrictedQueryMixin, self).get_queryset()
# Optional mutual exclusion check below...
if hasattr(self, 'filter_fields') and hasattr(self, 'filter_class'):
raise RuntimeError("%s has both filter_fields and filter_class" % self)
if hasattr(self, 'filter_class'):
filter_class = getattr(self, 'filter_class', None)
filters = set(filter_class.get_filters().keys())
elif hasattr(self, 'filter_fields'):
filters = set(getattr(self, 'filter_fields', []))
else:
filters = set()
for key in self.request.GET.keys():
if key in paging:
continue
if key not in filters:
return qs.none()
return qs