spleen
spleen

Reputation: 119

Django Model queries with relationships. How to do the right join

Let's say I have 2 Models:

class Auction(models.Model):
    seller = models.ForeignKey(User, on_delete=models.CASCADE, related_name="seller")
    title = models.CharField(max_length=64)

class Watchlist(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='user_watchlist')
    auction = models.ForeignKey(Auction, on_delete=models.CASCADE, related_name='auction_watchlist')

The view receives a request, creates a context variable with the auction objects the are:

  1. associated with the user who made the request and
  2. that have been added to the Watchlist Model,

sends it to the template.

I have set up my view to work like this:

@login_required
def watchlist(request): 
    watchlist_objects = Watchlist.objects.filter(user=request.user)
    auction_objects = Auction.objects.filter(auction_watchlist__in=watchlist_objects).all()
    context = {'watchlist_auctions': auction_objects}
    print(context)
    return render(request, "auctions/watchlist.html", context)

-I make the first query to get the list of items in the watchlist associate with the user.

-Then I use that to get another query from the Auction Model and I pass it to the template.

In the template I can access the attributes of Auction to display them. (title, author, and others that I did not include for simplicity)

The question is: Is this the "right way? Is there a better way to access the attributes in Auction from the first Watchlist query?

It seems to me that I'm doing something overcomplicated.

Upvotes: 1

Views: 162

Answers (1)

Jovan V
Jovan V

Reputation: 140

This is not that bad, considering that it will probably be executed as one query, because of the lazy queryset evaluations. You can skip the .all() if you already have .filter().

However, there is a more convenient way to do this, using lookups that span relationships.:

auction_objects = Auction.objects.filter(auction_watchlist__user_id=request.user.id)

Upvotes: 1

Related Questions