I have a Django auctions app, which has 3 models: Users, Listings, Bids. When a user tries to place a bid on some listing, I want to check if the new_bid field in Bid model is bigger than start current_bid field in Listing model and if the new_bid is <= 0, it should return a message.
This is what I’ve done so far but when I click on ‘Place bid’ button, it does not implement this, the page doesn’t redirect to an error page if the value is less than the current bid and doesn’t update the bid if the user adds another one.
VIEWS.PY
def listing_detail(request, listing_id):
try:
detail = get_object_or_404(Auction, pk=listing_id)
except Auction.DoesNotExist:
messages.add_message(request, messages.ERROR, "This is not available")
return HttpResponseRedirect(reverse("index"))
bid_count = Bids.objects.filter(auction=listing_id).count()
bid_form= BidForm()
if request.method == 'POST':
comment_form = CommentForm(request.POST)
if comment_form.is_valid():
new_comment = comment_form.save(commit=False)
new_comment.auction = detail
new_comment.save()
return redirect('listing_detail', listing_id=listing_id)
else:
comment_form = CommentForm()
else:
comment_form = CommentForm()
context = {'detail': detail,
'bid_count': bid_count,
'bid_form': bid_form,
'comment_form': comment_form
}
return render(request, 'auctions/details.html', context)
# create custom 404 page using learning.django
@login_required
def make_bid(request, listing_id):
if request.method == 'POST':
form = BidForm(request.POST)
if form.is_valid():
each_listing = Auction.objects.get(pk=listing_id)
highest_bid = Bids.objects.filter(auction_id=listing_id).order_by('-new_bid').first()
new_bid = form.cleaned_data.get['new_bid']
if new_bid <= 0:
return render(request, 'auctions/details.html',
{"message": "Input an amount greater than 0"})
# messages.add_message(request, messages.SUCCESS, "Input an amount greater than 0")
elif new_bid <= highest_bid.new_bid:
return HttpResponseRedirect(reverse("index"))
messages.add_message(request, messages.ERROR, "Amount is low, please increase the bid")
else:
highest_bid = Bids(each_listing=each_listing, user=request.user, new_bid=new_bid)
highest_bid.save()
each_listing.current_bid = new_bid
each_listing.save()
return HttpResponseRedirect(reverse("index"))
messages.add_message(request, messages.SUCCESS, "Your bid is currently the highest")
else:
form = BidForm()
return render(request, 'auctions/details.html', {'bidForm': form})
else:
form = BidForm()
return render(request, 'auctions/details.html', {'bidForm': form})
MODELS.PY
class Auction(models.Model):
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)
created_at = models.DateTimeField(auto_now_add=True)
category = models.ForeignKey(Category, max_length=12, null=True, blank=True, on_delete=models.CASCADE)
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')
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']
widgets = {
'title': forms.TextInput(attrs={'class': 'form-control'}),
'description': forms.Textarea(attrs={'class': 'form-control'}),
'current_bid': forms.NumberInput(attrs={'class': 'form-control'}),
'image_url': forms.URLInput(attrs={'class': 'form-control'}),
'category': forms.Select(attrs={'class': 'form-control'})
}
class BidForm(forms.ModelForm):
class Meta:
model = Bids
fields = ['new_bid']
labels = {
'new_bid': ('Bid'),
DETAILS.HTML
<form action="{% url 'listing_detail' detail.id %}" method="post">
{% csrf_token %}
{{ bid_form }}
<input type="submit" class="btn btn-primary btn-block mt-3" value="Place bid">
</form>