Reputation: 327
Let's say we have a Notification
model with manytomany=ManyToManyField(User, blank=True)
field with User
model.
How to annotate a field is_in_manytomany
to return boolean with True and False only depending on a condition, whether self.request.user
is in Notification
ManyToMany
field or not. This code below returns weird True
and False
and also None
, regardless of the default value of 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)
What am I doing wrong? How do you get a True/False annotation on the given condition?
Upvotes: 1
Views: 627
Reputation: 327
Okay, I hope this helps someone else: We need to put Q | Q in Q to achieve the results
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)
Explanation: we did not need to do manytomany__in=[user]
, because its a ManyToMany
field; manytomany=user
is enough, since some objects have manytomany=None
(because in my case the manytomany=ManyToManyField(User, blank=True)
, we need to add the second Q(manytomany=None)
. Also to reverse the boolean we can add ~
to any Q
expression.
Upvotes: 1