1👍
Try this in your template:
{{ post.l_auctions.get.current_bid_cmp }}
Update
I modified your models a bit so they make more sense to me. You might need your BaseModel for a good reason so feel free to modify to your needs. I also changed some names. There’s still things I see that don’t make a lot of sense in them but I’ll leave that to you.
models.py
from django.db import models
from django.conf import settings
class BaseModel(models.Model):
pass
class Category(models.Model):
name = models.CharField(max_length=20)
class Listing(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
category = models.ForeignKey(Category, on_delete=models.CASCADE)
title = models.CharField('Title of the auction', max_length=150, unique=True)
description = models.TextField('Description')
starting_bid = models.FloatField(default=False)
content = models.TextField('Content of auction')
image = models.ImageField('Referential Image', null=True,
upload_to='images_auctions', max_length=255, default='noimage.png')
def __str__(self):
return self.title
class Bid(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='offer_user')
listing = models.ForeignKey(Listing, null=True, on_delete=models.CASCADE, related_name='bids')
initialized_bid = models.BooleanField(default=False)
amount = models.FloatField('Current Bid', blank=True, null=True)
offer = models.FloatField(default=0, null=True, blank=True)
def __str__(self):
return str(self.amount)
class Meta:
get_latest_by = 'amount'
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{% for listing in object_list %}
<div class=" col-md-4 mt-4 ">
<div class="card " style="width: 18rem;">
<a href="#">
<img class="card-img-top img-fluid" src="{{ listing.image.url }}" alt="Card image cap">
</a>
<div class="card-body">
<a class="darklink" href="#">
<h5 class="card-title">{{ listing.title }}</h5></a>
<h5>Starting bid: $ {{ listing.starting_bid }}</h5>
<h5>Current bid: $ {{ listing.bids.latest }}</h5>
<p class="card-text">{{ listing.content | truncatechars:700 }}</p>
<a href="#" class="btn btn-danger btn-block">Show Auction</a>
</div>
</div>
</div>
{% endfor %}
</body>
</html>
Here’s an interactive session from a shell:
from django.contrib.auth import get_user_model
User = get_user_model()
admin = User.objects.get_or_create(username='admin')[0]
steve = User.objects.get_or_create(username='steve')[0]
jenny = User.objects.get_or_create(username='jenny')[0]
almond = User.objects.get_or_create(username='almond')[0]
from auctions.models import Category, Listing, Bid
c = Category.objects.get_or_create(name='General')[0]
l1 = Listing.objects.get_or_create(user=admin, category=c, title='Some title', description='description', starting_bid=1.00, content='content')[0]
b1 = Bid.objects.get_or_create(user=steve, listing=l1, amount=1.00)[0]
b2 = Bid.objects.get_or_create(user=jenny, listing=l1, amount=1.01)[0]
b3 = Bid.objects.get_or_create(user=almond, listing=l1, amount=1.02)[0]
>>> l1.bids.all()
<QuerySet [<Bid: 1.0>, <Bid: 1.01>, <Bid: 1.02>]>
You could get the max by:
Adding this to your class:
class Meta:
get_latest_by = 'amount'
and using listing.bids.latest()
…
Or using aggregate:
from django.db.models import Max
>>> l1.bids.aggregate(max=Max('amount'))
{'max': 1.02}
The key thing to note is, listing.bids
returns a "RelatedManager". This just means you can use familiar queryset methods like .all()
, .get()
, .filter()
, .last()
, .latest()
, etc. Many more.
In your case, you should first review this article on how to get the max of a queryset. Then decide how you want to proceed. In the example above, I put a class Meta
on the Bid
model which lets you get the latest object back based on the amount. This assumes the latest amount is always the highest, which might not be true for your situation.
One other thing you could do is add a @property
to your Listing
model.
class Listing(models.Model):
...
@property
def max_bid(self):
from django.db.models import Max
max_bid = self.bids.aggregate(max=Max('amount'))
if max_bid.get('max'):
return max_bid['max']
return ""
Use in your template like this:
<h5>Current bid: $ {{ listing.max_bid }}</h5>