列表上的Django,exclude()函数

时间:2015-05-07 09:20:47

标签: python django list django-queryset

我有一个列表,我将从中删除所有包含在其他列表中的元素。

所以,我想在“exclude”查询集中使用类似的内容。

现在这是我的代码:

list = Friend.objects.friends(self.request.user)
i_am_blocking = User.objects.filter(blocks_received__user_blocking=self.request.user)
is_blocking_me = User.objects.filter(blocks_set__user_blocked=self.request.user)
            blocked_users = list(chain(i_am_blocking, is_blocking_me))

现在我要从“list”中删除“blocked_users”中包含的所有项目。

有更好的方法吗?

2 个答案:

答案 0 :(得分:2)

您可以使用列表理解:

list = [friend for friend in list if friend.user not in blocked_users]

更新:要在ORM级别执行相同操作,您可以使用以下查询:

list = Friend.objects.friends(self.request.user) \
                     .exclude(user__in=blocked_users)

答案 1 :(得分:0)

稍微优化的版本:

friend_list = Friend.objects.friends(self.request.user)
i_am_blocking = User.objects.filter(...).values_list('pk', flat=True)
is_blocking_me = User.objects.filter(...).values_list('pk', flat=True)
blocked_users = set(chain(i_am_blocking, is_blocking_me))

friend_list = [friend for friend in friend_list if friend.user_id not in blocked_users]

这有两个主要优点。首先,blocked_usersset,因此user not in blocked_users不必遍历所有被阻止的用户以确定条件是否为真。其次,通过获取pk的列表,并与friend.user_id进行比较,您可以避免对每个可能的朋友进行额外查询:user_idfriend上的本地字段,而user是一个从数据库中提取整个user对象的访问器。

效率最高的仍然是在ORM级别进行过滤。顺便说一句,请不要为list分配任何内容。它会隐藏内置list()类型,如果需要,您可以使用list_,但通常最好使用更具描述性的名称。