首页 > 解决方案 > 在views.py中设置字段的最小属性HTML表单值

问题描述

我正在阅读这篇文章,以了解如何在表单初始化后设置字段的值。我在 Django 的文档中没有看到这一点,或者我输入了错误的查询,但是有没有办法在 views.py 中设置字段的 'min' 属性值?我问是因为最小值可以不断变化,因为它是每次用户出价高于函数highest_bid中的变量值时设置的出价金额view_listing

模型.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}"

表格.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': '' })
        }

视图.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>

在我的views.py文件的“GET”部分中bid_form.initial['bid_amount'] = highest_bid,我还想在每次更改时将bid_form['bid_amount']最小值设置为值highest_bid,这样用户就不能输入低于highest_bid表单字段的任何内容。这完全可以在views.py文件中设置吗?我试过bid_form['bid_amount'].min了,但这显示在控制台中<built-in method min of decimal.Decimal object at 0x7f99172a82d0>

标签: djangodjango-viewsdjango-forms

解决方案


您可以创建一个自定义函数来检查所有其他出价金额,如果新出价低于任何以前的出价,则返回验证错误

def validate_highest_bid(value):
    bids = Bid.objects.all()
    for bid in bids:
        if value <= bid.bid_amout:
            raise ValidationError(
            f"{value} must be higher than previous value",
            params={'value': value},
        )
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, validators=[validate_highest_bid])

    def __str__(self):
        return f"{self.user}'s bid on {self.listing} is {self.bid_amount}"

然后,您可以在保存时添加一些处理错误的内容


推荐阅读