Django:如果对象在带有过滤器的列表中,则检查具有 manytomany 字段的模型

问题描述

假设我们有一个带有 Notification 字段的 manytomany=ManyToManyField(User,blank=True) 模型和 User 模型。 如何注释字段 is_in_manytomany 以仅根据条件返回带有 True 和 False 的布尔值,无论 self.request.user 是否在 Notification ManyToMany 字段中。无论 True认值如何,下面的代码都会返回奇怪的 FalseNone 以及 BooleanField

user = User.objects.get(id=1)

qs = Notification.objects.all().annotate(
                is_in_manytomany =ExpressionWrapper(
                    Q(manytomany__in = [user]),output_field=BooleanField(default=True)
                )
            )

for item in qs:
    print(item.is_in_manytomany)

我做错了什么?如何在给定条件下获得 True/False 注释?

解决方法

好的,我希望这对其他人有所帮助: 我们需要把 Q | Q in Q 达到的结果

user = User.objects.get(id=1)

qs = Notification.objects.all().annotate(
                is_in_manytomany=ExpressionWrapper(
                    Q(Q(manytomany=user)| Q(manytomany=None)),output_field=BooleanField()
                )
            )

for item in qs:
    print(item.is_in_manytomany)

说明:我们不需要做manytomany__in=[user],因为它是一个ManyToMany字段; manytomany=user 就足够了,因为有些对象有 manytomany=None(因为在我的例子中是 manytomany=ManyToManyField(User,blank=True),我们需要添加第二个 Q(manytomany=None)。另外为了反转布尔值,我们可以添加 { {1}} 到任何 ~ 表达式。