#How to add attribute to json that's associated with model

11 messages · Page 1 of 1 (latest)

brave sandal
#

I have three models

-Company
-User
-Queue

A Company has a OneToOne relationship with a Queue
A User has a many to many relationship with a Queue. So a user can join many queues, and a queue can contain many users.

When a user makes a request for their restaurants, I want a json response like below that shows all the restaurants and whether a user has joined them or not.

[
  {
    name: 'KFC',
    location: 'america',
    joined: false
  },
  {
    name: 'McDonalds',
    location: 'australia',
    joined: true
  }
]

To preface, I've got an endpoint for a user to join a queue, and what this does is add the associate a User with a Queue (via an intermediate QueueDetails model).

I am sorta confused on where to add joined. I can't add joined as an attribute to the Company model since it's not an actual part of a Company and more of a User associated thing. So I'm just not sure really how I add joined.

marble topaz
#

You'd define a joined field on the Company serializer, then annotate the querysets to calculated the joined value for the user. Does that make sense from a high level?

#

Another way to think about the problem is to split the API endpoint into two endpoints. One endpoint would return companies the user is related to. The other endpoint would return companies the user isn't related to.

brave sandal
marble topaz
#

Yup, that's another great way to do it.

#

If you want to get real fancy with it, in the view you can dynamically change what serializer is used in the get_serializier_class method.

#

But that's a bit hard to document.

brave sandal
#

Ah ill read up on that thanks for the tip

brave sandal
# marble topaz You'd define a `joined` field on the Company serializer, then annotate the query...

I've just started working on it and am stuck on the annotate portion (companies.annotate(joined=user in each_companys queue). How can I annotate each company with whether a user has joined the queue or not? Seems that you can only use query expressions in annotate and am unsure how those really work in this situation

views.py

class UserCompanyList(APIView):
    
    def get(self, request, **kwargs):
        user = request.user
        
        companies = Company.objects.all()
        
        # How to check whether a user has joined for every company's queue?
        
        companies.annotate(joined=user in each_companys queue)

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")

    def __str__(self) -> str:
        return f"{self.company}'s queue"

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,
    )
marble topaz
#

You could use Case/When or exists.

brave sandal
#

Got it working, thanks