我正在使用django-rest-framework
django-filter
。我需要检索date
属性为None
的小部件列表,但无论我尝试了什么查询,我都会得到空的响应或完整的,未经过滤的响应。
以下是我定义viewset和filterset的方法。
class WidgetFilter(django_filters.FilterSet):
date = django_filters.DateTimeFilter(name='date', lookup_type='exact')
no_date = django_filters.DateTimefilter(name='date', lookup_type='isnull')
class Meta:
model = Widget
fields = ['date',]
class WidgetSet(viewsets.ModelViewSet):
model = Widget
filter_class = WidgetFilter
以下查询会导致空[]
响应:
?date=None
?date=0
?date=NULL
?date=False
?date=2012-05-24T11:20:06Z # a known and correct date
以下查询会导致返回所有对象:
?date=
?no_date=True
?no_date=False
?no_date=1
?no_date=0
非常感谢任何帮助!我一直无法通过None
找到有关使用日期(或将django-filter
作为过滤器值传递)django-rest-framework
的任何信息。
如果没有更优雅的方式,这就是我提出的解决方法,但我仍然想知道使用django-filter
的解决方案,如果存在的话。
class WidgetSet(viewsets.ModelViewSet):
model = Widget
def get_queryset(self):
if 'no_date' in self.request.QUERY_PARAMS:
return self.model.objects.filter(date=None)
return self.model.objects.all()
答案 0 :(得分:8)
直接在过滤器的isnull
参数中指定name
'date__isnull'
似乎对Django REST Framework 3.1.3起作用。
class WidgetFilter(django_filters.FilterSet):
date = django_filters.DateTimeFilter(name='date')
no_date = django_filters.BooleanFilter(name='date__isnull')
class Meta:
model = Widget
fields = []
答案 1 :(得分:6)
我今天遇到了类似的情况,看起来好像开箱即用django rest framework *支持这个过滤器:
~/your_endpoint/?date__isnull=True
这与等效ORM查询的外观相匹配。如果这很丑陋,您可以使用文档示例将该查询参数转换为其他内容而不必覆盖get_queryset
答案 2 :(得分:4)
如果没有更优雅的方式,这就是我提出的解决方法,但我仍然想知道使用django-filter
的解决方案,如果存在的话。
class WidgetSet(viewsets.ModelViewSet):
model = Widget
def get_queryset(self):
if 'no_date' in self.request.QUERY_PARAMS:
return self.model.objects.filter(date=None)
return self.model.objects.all()
答案 3 :(得分:3)
正在运行django-filter==1.0.4
和djangorestframework==3.6.3
。
正确答案无效,因为django-filter
中的模块路径已更改(BooleanFilter已移至django_filters.rest_framework)。
__isnull
也不起作用,我不得不使用lookup_expr:
from django_filters import rest_framework as filters
class WidgetFilter(filters.FilterSet):
no_date = filters.BooleanFilter(name='date', lookup_expr='isnull')
class Meta:
model = Widget
fields = ( 'date')
得到答案
过滤“无日期”
答案 4 :(得分:0)
我已经为选择过滤器做了这个,这(可以说)更有用:
class NullableChoiceFilter(django_filters.ChoiceFilter):
def __init__(self, **kwargs):
choices = dict(kwargs['choices'])
null_text = choices.pop(None, 'null')
kwargs['choices'] = ((None, '------'), ('null', null_text)) + tuple(choices.items())
super().__init__(**kwargs)
def filter(self, qs, value):
if value == 'null':
return super().filter(qs, Lookup(lookup_type='isnull', value=True))
else:
return super().filter(qs, value)
然后
class MyFilterSet(filters.FilterSet):
class Meta:
model = ...
@classmethod
def filter_for_lookup(cls, f, lookup_type):
if lookup_type == 'exact' and f.choices:
return NullableChoiceFilter, {'choices': f.choices}
return filters.FilterSet.filter_for_lookup(f, lookup_type)
我知道这并没有完全回答你的问题,但这是" django rest framework filter null的第一个google结果。"
答案 5 :(得分:0)
更新:name
现在必须是field_name
...,而filter_class
现在是filterset_class
。
from django_filters import rest_framework as filters
class WidgetFilter(filters.FilterSet):
no_date = filters.BooleanFilter(name='date', lookup_expr='isnull')
class Meta:
model = Widget
fields = ('date')
class WidgetSet(viewsets.ModelViewSet):
model = Widget
filterset_class = WidgetFilter