我有一个列表,我将从中删除所有包含在其他列表中的元素。
所以,我想在“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
”中包含的所有项目。
有更好的方法吗?
答案 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_users
是set
,因此user not in blocked_users
不必遍历所有被阻止的用户以确定条件是否为真。其次,通过获取pk
的列表,并与friend.user_id
进行比较,您可以避免对每个可能的朋友进行额外查询:user_id
是friend
上的本地字段,而user
是一个从数据库中提取整个user
对象的访问器。
效率最高的仍然是在ORM级别进行过滤。顺便说一句,请不要为list
分配任何内容。它会隐藏内置list()
类型,如果需要,您可以使用list_
,但通常最好使用更具描述性的名称。