Django,列表中的排除()函数

Django, exclude() function on list

我有一个列表,我想从中删除另一个列表中包含的所有元素。

所以,我希望在列表中有类似“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”中包含的所有项目。

有更好的方法吗?

您可以使用列表理解:

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

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

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

稍微优化的版本:

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_users 是一个 set,因此 user not in blocked_users 不必遍历所有被阻止的用户来确定条件是否为真。其次,通过获取 pk 的列表,并与 friend.user_id 进行比较,您可以避免对每个可能的朋友进行额外的查询:user_idfriend 上的本地字段,而 user 是一个访问器,它从数据库中获取整个 user 对象。

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