1

I'd appreciate your help. I have two models. In the Bids model you will find current_bid_cmp. I would like from the ListingAuctions model to be able to access the corresponding current_bid_cmp of the Bids model. I only have found information to do querys from the model which contains the foreingKey.

My view: I use get_context_data because I have been trying anothers querys. perhaps its not the more aproppiate

class index(ListView):
    
    model = ListingAuctions
    template_name = "auctions/index.html"

    def get_context_data(self, **kwargs):
            
            context = super().get_context_data(**kwargs)
            context['object'] = ListingAuctions.objects.all()
            
            
            
            return context

My Models:

class ListingAuctions(BaseModel):

   title_auction = models.CharField('Title of the auction',max_length = 150, unique = True)
   description = models.TextField('Description')
   user = models.ForeignKey(User, on_delete = models.CASCADE)
   category = models.ForeignKey(Category, on_delete = models.CASCADE)
   initial_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')
   
class Bids(BaseModel):
   user = models.ForeignKey(User, on_delete = models.CASCADE, related_name='offer_user')
   listing_auctions = models.ForeignKey(ListingAuctions,null=True, on_delete= models.CASCADE, related_name='l_auctions')
   initialized_bid = models.BooleanField(default=False)
   current_bid_cmp = models.FloatField('Current Bid Cmp',blank=True, null=True )
   offer = models.FloatField(default=0 ,null=True, blank=True)
   

My HTML

Current bid: $ {{post.l_auctions.current_bid_cmp}}
its my attemp l_auctions is the relate name from listing_auctions in Bids model. Post is a ListingAuction object:
{% for post in object_list %}
<div class=" col-md-4 mt-4 ">

    <div class="card " style="width: 18rem;">
        <a  href="{% url 'auctions_detail' post.pk %}">
      <img class="card-img-top img-fluid" src="{{ post.image.url }}" alt="Card image cap" >
      </a>
      
      <div class="card-body">
        <a class="darklink" href="{% url 'auctions_detail' post.pk %}"> <h5 class="card-title">{{post.title_auction}}</h5></a>
        <h5>Starting bid: $ {{post.initial_bid}}</h5>
        <h5>Current bid: $ {{post.l_auctions.current_bid_cmp}}</h5>
        <p class="card-text">{{post.content | truncatechars:700 }}</p>
        <a href=" {% url 'auctions_detail' post.pk %}" class="btn btn-danger btn-block">Show Auction</a>
      </div>
    </div>
            
</div>
{% endfor %}

2 Answers2

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>
Jarad
  • 17,409
  • 19
  • 95
  • 154
  • This is new for me. Am I to assume that it is filtered like get() in a query ? Maybe there is another similar option to do something like filter().latest('id') because it gives me the following error: Exception Value: get() returned more than one Bids -- it returned 3! – Rodolfo Schiavi Jul 03 '22 at 12:24
  • @RodolfoSchiavi so for the current bid, you just want to show the maximum bid then, is that right? – Jarad Jul 04 '22 at 05:24
  • Yes it is that. I need to display the last value. I have tried with: {{ post.l_auctions.current_bid_cmp | last }} But it still doesn't show me current_bid_cmp in the template – Rodolfo Schiavi Jul 04 '22 at 12:38
  • Thanks a lot! The get_latest_by = 'amount' worked for me. I haven't changed the names of the variables yet because I didn't want to fall into another bug or confusion... But I'll finally try it. Thanks again and I will be studying more this given material. – Rodolfo Schiavi Jul 05 '22 at 12:11
0

Use in your Jinja Template

 {{object_list.0.l_auctions.current_bid_cmp}}