【问题标题】:Django Rest Framework OneToOneField related BooleanFilterDjango Rest Framework OneToOneField 相关 BooleanFilter
【发布时间】:2017-03-07 05:43:47
【问题描述】:

我正在使用 django 和 rest-framework。

现在我有具有 OneToOne 关系的模型:

class ModelA(models.Model):
    pass

class ModelB(models.Model):
    a = models.OneToOneField(
        A, related_name='b')

我在 A 上应用了一个 ViewSet:

class ModelAViewSet(viewsets.ModelViewSet):
    queryset = ModelA.objects.all()
    serializer_class = ModelASerializer

然后,我想在ModelAViewSet 上添加一个BooleanFilter 来过滤ModelA 对象是否有相关的ModelB 对象。

我尝试了以下方法:

class ModelAViewSet(viewsets.ModelViewSet):
    class Filter(FilterSet):
        has_b = filters.BooleanFilter('b')
    queryset = ModelA.objects.all()
    serializer_class = ModelASerializer
    filter_fields = ['has_b']

所以,如果它有效,我们得到:

  1. ?has_b=1:不过滤返回所有记录;
  2. ?has_b=2:返回有相关ModelA对象的记录;
  3. ?has_b=3:返回NO NOTModelA对象相关的记录;

除了上面的情况 3 之外,它几乎成功了。

那么正确的做法是什么?

【问题讨论】:

  • 为什么要将数字传递给布尔过滤器?
  • 我传递了相关的 OneToOneField 这根本不是布尔结果,可能我应该做一个查询集查找字符串,但我可以找到解决方案。
  • @Sayse 默认小部件是 django 的 NullBooleanSelect,它使用这些选项。如果您使用的是最新版本的 django-filter,则可以改为执行以下操作:from django_filters.rest_framework import FilterSet, filters。子包中的BooleanFilter 改为使用自定义的BooleanWidget

标签: python django rest django-rest-framework django-filter


【解决方案1】:
from django_filters.rest_framework import FilterSet, filters

class Filter(FilterSet):
    has_b = filters.BooleanFilter(name='b', lookup_expr='isnull', exclude=True)

这里有三个变化:

  1. 通过从rest_framework子包导入,使用API​​友好的BooleanWidget,因此您可以查询?has_b=true而不是?has_b=1

  2. 过滤器使用isnull 查找,它允许您测试相关模型是否存在。

  3. b__isnull=True 正在测试相关B缺乏,这与您想要的相反。使用 exclude=True 会反转逻辑,以便您改为过滤具有相关 BAs。

等效的.filter() 调用:

# before, incorrect
A.objects.filter(b=True)

# after, correct
A.objects.exclude(b__isnull=True)

【讨论】:

    猜你喜欢
    • 2018-02-16
    • 2015-03-24
    • 1970-01-01
    • 2018-10-14
    • 2018-11-11
    • 2015-06-23
    • 1970-01-01
    • 1970-01-01
    • 2014-11-27
    相关资源
    最近更新 更多