Django REST框架:使用组合过滤器从另一个查询集中排除

时间:2017-01-23 10:27:19

标签: python django django-queryset django-filters

我有以下方法返回is_active=True和特定用户的对象。

def filter_active_user(self, queryset, name, value):
    return queryset.filter(active_states__is_active=True,
                           active_states__user_id=value)

我想构建一个方法,它将返回一个查询集,其中包含上述方法中未包含的所有对象。所以我使用exclude创建了以下方法:

def filter_inactive_user(self, queryset, name, value):
    return queryset.exclude(active_states__is_active=True,
                            active_states__user_id=value)

我还使用~Q尝试了以下实现:

def filter_inactive_user(self, queryset, name, value):
    return queryset.filter(~Q(active_states__is_active=True,
                              active_states__user_id=value))

但是,我没有得到正确的结果。 例如,在测试用例中,我创建了一些由3个对象组成的数据。使用方法filter_active_user我获得了1个对象,我希望使用filter_inactive_user方法获得另外2个对象,但我也得到了1.更具体地说,下面提到我的测试数据:

record_1.set_active_states_for_users([self.user1.uuid], True)
record_2.set_active_states_for_users([self.user1.uuid], False)
record_2.set_active_states_for_users([self.user2.uuid], True)
record_3.set_active_states_for_users([self.user2.uuid], False)

当我使用filter_active_user user=user2时,我获得了record_2。 当我使用filter_inactive_user user=user2时,我只获取record_1而不是record_3。 你能帮我构建一个在查询集中组合两个过滤器的正确方法吗?

1 个答案:

答案 0 :(得分:2)

解决方案1:

def filter_inactive_user(self, queryset, name, value):
    qs_active = queryset.filter(active_states__is_active=True, active_states__user_id=value)
    qs_inactive = queryset.exclude(pk__in=qs_active.values_list('pk', flat=True))

解决方案2:

def filter_inactive_user(self, queryset, name, value):
    qs_inactive = queryset.exclude(active_states__is_active=True).exclude(active_states__user_id=value)