I'm using DRF. I've got the following code where I annotate a queryset of Company
objects with an additional joined
field. It seems annotate
is adding an extra object to my queryset.
views.py
def get(self, request, **kwargs):
user = request.user
companies = Company.objects.all()
print(companies)
user_in_queue = When(queue__users=user, then = True)
companies = Company.objects.annotate(joined=Case(
user_in_queue, default = False
))
print(companies)
models.py
class Company(models.Model):
name = models.CharField(max_length=15, unique=True)
def __str__(self) -> str:
return self.name
class User(AbstractUser):
def __str__(self) -> str:
return f"{self.username}"
class Queue(models.Model):
company = models.OneToOneField(
Company, on_delete=models.CASCADE, related_name="queue"
)
users = models.ManyToManyField(User, through="QueueDetails", related_name="queues")
class QueueDetails(models.Model):
queue = models.ForeignKey(
Queue,
related_name="queue_details",
on_delete=models.CASCADE,
)
user = models.ForeignKey(
User,
related_name="queue_details",
on_delete=models.CASCADE,
)
the first print
gives me
<QuerySet [<Company: kfc>, <Company: kfc>]>
With a json of
[
{
"name": "kfc",
"id": 1,
},
{
"name": "kfc",
"id": 2,
}
]
The second gives me
<QuerySet [<Company: kfc>, <Company: kfc>, <Company: kfc>]>
With a json of
[
{
"name": "kfc",
"id": 1,
"joined": null
},
{
"name": "kfc",
"id": 1,
"joined": true
},
{
"name": "kfc",
"id": 2,
"joined": null
}
]
I want a json of
[
{
"name": "kfc",
"id": 1,
"joined": true
},
{
"name": "kfc",
"id": 2,
"joined": null
}
]
CodePudding user response:
You want to work with an Exists
subquery [Django-doc] to prevent joining:
from django.db.models import Exists, OuterRef
def get(self, request, **kwargs):
user = request.user
companies = Company.objects.annotate(
joined=Exists(
Queue.objects.filter(company_id=OuterRef('pk'), users=request.user)
)
)
# …
For the serializer, you add a joined
field:
class CompanySerializer(serializers.ModelSerializer):
joined = serializers.BooleanField()
# …