I am creating an ebay like aunction site, the details view page should reflect details from two models.
One of the models has the details of the current_bid (this is created when creating the listing), there is also the second model that contains new_bids (this is where the users who want to purchase the item can input their bids).
The issue(s) I'm having is how to put two models in my details view and also if you can confirm my current logic in finding out the highest bid (if this is correct or not).
MODELS.PY
class Auction(models.Model):
ABSTRACT = 'AB'
MODERN = 'MN'
ILLUSTRATION = 'IN'
select_category = [
('ABSTRACT', 'Abstract'),
('MODERN', 'Modern'),
('ILLUSTRATION', 'Illustration')
]
title = models.CharField(max_length=25)
description = models.TextField()
current_bid = models.IntegerField(null=False, blank=False)
image_url = models.URLField(verbose_name="URL", max_length=255, unique=True, null=True, blank=True)
category = models.CharField(
choices=select_category,
max_length=12,
default=MODERN,
null=True, blank=True
)
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
class Meta:
ordering = ['-created_at']
class Bids(models.Model):
auction = models.ForeignKey(Auction, on_delete=models.CASCADE, related_name='bidding')
user = models.ForeignKey(User, on_delete=models.PROTECT, related_name='bidding')
new_bid = models.DecimalField(max_digits=8, decimal_places=2)
# new_bid = MoneyField(max_digits=10, decimal_places=2, null=False, blank=False, default_currency='USD', default=0)
done_at = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ['auction', '-new_bid']
FORMS.PY
class AuctionForm(forms.ModelForm):
class Meta:
model = Auction
fields = ['title', 'description', 'current_bid', 'image_url', 'category']
class BidForm(forms.ModelForm):
class Meta:
model = Bids
fields = ['new_bid']
labels = {
'new_bid': ('Choose your maximum bid'),
}
VIEWS.PY
def listing_detail(request, listing_id):
detail = get_object_or_404(Auction, pk=listing_id)
if detail == None:
messages.add_message(request, messages.ERROR, "This is not available")
return HttpResponseRedirect(reverse("index"))
bid_queryset = Bids.objects.filter(detail=listing_id).order_by('new_bid').first()
if bid_queryset == None:
bid = detail.current_bid
else:
bid = bid_queryset.new_bid
context = {'detail': detail}
return render(request, 'auctions/details.html', context)
@login_required
def make_bid(request, listing_id):
bid_item = get_object_or_404(Bids, pk=listing_id)
each_listing = Auction.objects.get(pk=listing_id)
try:
highest_bid = each_listing.bidding.order_by('-new_bid')[0]
except Bids.DoesNotExist:
highest_bid = 0
if request.method == 'POST':
form = BidForm(request.POST)
if form.is_valid:
if form['bidding'] > highest_bid:
bidding = form.save()
messages.add_message(request, messages.SUCCESS, "Your bid is currently the highest")
return HttpResponseRedirect(reverse("index"))
else:
messages.add_message(request, messages.ERROR, "Your bid must be higher than the previous bid")
else:
form = BidForm(initial={'each_listing': each_listing,
'user': request.user,
'amount': highest_bid})
return render(request, 'auctions/details.html', {'form': form})
DETAILS.HTML
<section>
<div >
<div >
{% if detail.image_url %}
<img src='{{ detail.image_url }}' alt="{{ detail.title }}" style="width:100%">
{% else %}
<img src="https://demofree.sirv.com/nope-not-here.jpg">
{% endif %}
</div>
<div >
<div style="width: 30rem;">
<div>
<h5>{{ detail.title }}</h5>
<hr>
<p>{{ detail.description }}</p>
<hr>
<p>{{ detail.current_bid }}</p>
<hr>
<p>{{ detail.new_bid }}</p>
<hr>
<button >Place bid</button>
<button >Add to watchlist</button>
</div>
</div>
</div>
<form action="{% url 'auctions:listing_detail' listing.id %}" method="post">
{% csrf_token %}
{{form.as_p}}
<input type="submit" value="Submit">
</form>
Right now, I'm having this error message
FieldError at /detail/15/
Cannot resolve keyword 'detail' into field. Choices are: auction, auction_id, done_at, id, new_bid, user, user_id
Traceback Switch to copy-and-paste view
C:\Users\USER\AppData\Local\Programs\Python\Python310\lib\site-packages\django\core\handlers\exception.py, line 47, in inner
response = get_response(request) …
Local vars
C:\Users\USER\AppData\Local\Programs\Python\Python310\lib\site-packages\django\core\handlers\base.py, line 181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs) …
Local vars
C:\Users\USER\Downloads\commerce\commerce\auctions\views.py, line 95, in listing_detail
bid_queryset = Bids.objects.filter(detail=listing_id).order_by('new_bid').first()
URLS.PY
urlpatterns = [
path("", views.index, name="index"),
path("create/", views.create_listing, name="create_listing"),
path("detail/<int:listing_id>/", views.listing_detail, name="listing_detail"),
path("bid/<int:listing_id>/", views.make_bid, name="bid"),
CodePudding user response:
Either you should add pk or id field in listing_detail view
Try this :
def listing_detail(request, listing_id):
detail = get_object_or_404(Auction, pk=listing_id)
if detail == None:
messages.add_message(request, messages.ERROR, "This is not available")
return HttpResponseRedirect(reverse("index"))
bid_queryset = Bids.objects.filter(pk=listing_id).order_by('new_bid').first() # change here
if bid_queryset == None:
bid = detail.current_bid
else:
bid = bid_queryset.new_bid
Note :
Change this {% url 'auctions:bid' listing.id %} to {% url 'bid' listing.id %} make sure that listing.id is from template variables.