I was looking through this article to figure out how to set a field's value after a form is initialized. I don't see this in Django's docs, or maybe I'm putting in the wrong query, but is there a way to set the 'min' attribute value of a field in views.py? I'm asking because the min value can change constantly since it's a bid amount that is set each time a user bids above the highest_bid
variable value in the view_listing
function.
models.py
class Bid(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
listing = models.ForeignKey(Listing, on_delete=models.CASCADE, null=True)
bid_amount = models.DecimalField(decimal_places=2, max_digits=10)
def __str__(self):
return f"{self.user}'s bid on {self.listing} is {self.bid_amount}"
forms.py
class BidForm(ModelForm):
class Meta:
model = Bid
fields = ('bid_amount',)
labels = { 'bid_amount': ('Your Bid'), }
widgets = {
'bid_amount': forms.NumberInput(attrs={'step': 00.50, 'class': 'form-control', 'style': 'width:50%', 'min': 0, 'title': '', 'placeholder': '' })
}
views.py
@login_required
def view_listing(request, listing_id):
listing = get_object_or_404(Listing, pk=listing_id)
bids = Bid.objects.filter(listing=listing)
all_bids = [] # Set an empty bid list to get all bids if any exist
highest_bid = listing.starting_price # Set highest bid to 0 in case there are no bids
if bids:
bid_list = list(bids) # Convert Queryset to a list
for index in bid_list:
all_bids.append(index)
highest_bid = all_bids[-1].bid_amount # Get the highest bid from all_bids
listing.starting_price = highest_bid
else:
highest_bid # Else highest bid is 0
if request.method == "GET":
bid_form = BidForm()
# Bid must be at least equal to highest bid
bid_form.initial['bid_amount'] = highest_bid
print(bid_form.initial['bid_amount'])
try: # Check if the item is in the user's watchlist and pass the user's wishlist item name if it does
Watchlist.objects.get(user=request.user, listing=listing)
list_item = Watchlist.objects.get(user=request.user, listing_id=listing_id)
return render(request, "auctions/viewlisting.html" , { "listing": listing, "item": list_item, "bids": bids, "bid_form": bid_form, "highest_bid": highest_bid })
except: # else return None
None
return render(request, "auctions/viewlisting.html" , { "listing": listing, "bids": bids, "bid_form": bid_form, "highest_bid": highest_bid })
else: # On POST, allow a user to bid on an item
try:
bid_form = BidForm(request.POST)
newbid = bid_form.save(commit=False)
newbid.user = request.user
if bid_form.is_valid():
bid_amount = request.POST.get("bid_amount")
# Got bid value from form. Left off here
bid_value = bid_form.cleaned_data['bid_amount']
if bid_value <= highest_bid:
messages.error(request, f"Your bid must be greater than ${highest_bid}")
return HttpResponseRedirect(listing.get_absolute_url())
bid = Bid.objects.create(
listing=listing, user=request.user, bid_amount=bid_amount
)
bid.save()
messages.success(request, "Your bid was saved.")
return HttpResponseRedirect(listing.get_absolute_url())
return redirect("auctions:index")
except ValueError:
messages.error(request, "Your bid was not accepted.")
return render(request, "auctions/viewlisting.html", { "listing": listing, "error": ValueError })
viewlisting.html
some html code...
<!-- my bid form --!>
<form action="" method="POST">
{% csrf_token %} {{ bid_form.as_p }}
<input type="submit" value="Submit Your Bid" class="btn btn-danger">
</form>
In the "GET" section of my views.py file, where bid_form.initial['bid_amount'] = highest_bid
is set, I also want to set the bid_form['bid_amount']
min value to highest_bid
value each time it changes so that the user cannot enter anything lower than highest_bid
in the form field. Is this at all possible to set in the views.py file? I've tried bid_form['bid_amount'].min
but this shows up in the console <built-in method min of decimal.Decimal object at 0x7f99172a82d0>