django related question querying list of won items by getting list of items then max bid from bid table for each item then check if user won it

Viewed 32

I have a question here, I have two tables in my django models one for listings and one for bids

class Listing(models.Model):
class Meta:
    verbose_name_plural = 'Listing'
title = models.CharField(max_length=64)
description = models.TextField()
price = models.DecimalField(max_digits=5, decimal_places=2)
image = models.URLField(max_length=500, default='')
category = models.CharField(max_length=32)
created = models.CharField(max_length=32)
addedon = models.DateTimeField(auto_now_add=True)
active = models.BooleanField(default=True)

def __str__(self):
    return self.title


class Bid(models.Model):
class Meta:
    verbose_name_plural = 'Bid'

user = models.ForeignKey(User, on_delete=models.CASCADE)
item = models.ForeignKey(Listing, on_delete=models.CASCADE)
bid = models.DecimalField(max_digits=5, decimal_places=2)
created = models.DateTimeField(auto_now_add=True)
 

what i want is to show a page with all the user won items

 def won(request):
listing = Listing.objects.filter(active=False)

the question here how i can make list of all then check max bid of each listing, then check is the current user is the winner and display it in the template won.html like :

 getMaxBid = Bid.objects.filter(item_id=listing.id).aggregate(Max('bid'))
            maxBid = getMaxBid['bid__max']

then if the user is the winner display it

return render(request, "auctions/won.html", {
    'listing': listing, 'active': False
})

thanks in advance

1 Answers

You can filter the Listing by first creating a Subquery expression [Django-doc] that will obtain the winner, and then check if the logged in user (or another user) is the winner, so:

from django.db.models import OuterRef, Subquery

listing = Listing.objects.alias(
    bid_winner=Subquery(
        Bid.objects.filter(item=OuterRef('pk')).order_by('-bid').values('user')
    )[:1]
).filter(
    active=False,
    bid_winner=request.user
)

or Listings where the user has an active bid:

Listing.objects.filter(
    bid__user=request.user,
    active=True
).distinct()
Related