如何验证 Django 中的表单字段?
How to validate form field in django?
我想确保 bid field
的当前值不小于当前最大值 bid
。这是我使用自定义 clean
方法的表单。
表格:
class Place_A_Bid_Form(forms.Form):
listing = forms.CharField(widget=forms.TextInput(attrs={"type":"hidden"}))
bid = forms.IntegerField(widget=forms.NumberInput(attrs={"class":"form-control"}), min_value=1)
def clean_bid(self, biggestBid):
bid = self.cleaned_data["bid"]
if bid < biggestBid:
raise ValidationError("""New bid shouldn't be less than starting bid, or
if any bids have been placed then new bid
should be greater than current biggest bid""")
return bid
查看:
def place_a_bid(request):
if request.method == "POST":
form = Place_A_Bid_Form(request.POST)
user = User.objects.get(username=request.user.username)
biggest_bid = Bid.objects.filter(user=user).aggregate(Max("amount"))
if form.is_valid():
data = form.cleaned_data
user_obj = User.objects.get(username=request.user.username)
listing_obj = Listing.objects.get(title=data["listing"])
Bid.objects.update_or_create(
user=user_obj,
listing=listing_obj,
amount=data["bid"]
)
return redirect(listing_obj)
鉴于我正在提取要与之比较的当前值,但我不知道如何将此值传递给我的表单字段的 clean
方法。或者也许我做错了?那么如何正确地进行这种验证呢?
class Place_A_Bid_Form(forms.Form):
listing = forms.CharField(widget=forms.TextInput(attrs={"type":"hidden"}))
bid = forms.IntegerField(widget=forms.NumberInput(attrs={"class":"form-control"}),
min_value=1)
def __init__(self,biggestBid=0 *args, **kwargs):
super().__init__(*args, **kwargs)
self.biggestBid = biggestBid
def clean_bid(self):
bid = self.cleaned_data["bid"]
if bid < self.biggestBid:
raise ValidationError("""New bid shouldn't be less than starting bid, or
if any bids have been placed then new bid
should be greater than current biggest bid""")
return bid
然后在 views.py:
def place_a_bid(request):
if request.method == "POST":
dict = Bid.objects.filter(user=user).aggregate(Max("amount"))
form = Place_A_Bid_Form(biggestBid=dict['amount__max'], data=request.POST)
user = User.objects.get(username=request.user.username)
if form.is_valid():
data = form.cleaned_data
user_obj = User.objects.get(username=request.user.username)
listing_obj = Listing.objects.get(title=data["listing"])
Bid.objects.update_or_create(
user=user_obj,
listing=listing_obj,
amount=data["bid"]
)
return redirect(listing_obj)
Django 的 IntegerField
[Django-doc] 可以在没有任何额外逻辑的情况下验证最小值,您可以设置 .min_value
并添加一个验证器:
from django.core.validators import MinValueValidator
class Place_A_Bid_Form(forms.Form):
listing = forms.CharField(widget=forms.TextInput(attrs={'type': 'hidden'}))
bid = forms.IntegerField(widget=forms.NumberInput(attrs={'class':'form-control'}))
def __init__(self, *args, **kwargs, min_bid=0):
super().__init__(*args, **kwargs)
bid = self.fields['bid']
min_bid += 1
bid<strong>.min_value = min_bid</strong>
bid<strong>.validators.add(MinValidator(min_bid))</strong>
那么你只需要将 min_bid
传递给表单:
from django.contrib.auth.decorators import login_required
@login_required
def place_a_bid(request):
biggest_bid = Bid.objects.filter(user=request.user).aggregate(
min_bid=Max('amount')
)['min_bid'] or 0
if request.method == 'POST':
form = Place_A_Bid_Form(request.POST<strong>, min_bid=biggest_bid</strong>)
if form.is_valid():
data = form.cleaned_data
listing_obj = Listing.objects.get(title=data['listing'])
Bid.objects.update_or_create(
user=request.user,
listing=listing_obj,
amount=data['bid']
)
return redirect(listing_obj)
else:
form = Place_A_Bid_Form(<strong>min_bid=biggest_bid</strong>)
return render(request, '<em>app_name</em>/name-of-template.html', {'form': form})
在 GET 请求的情况下,这也构建了一个表单,将最大出价作为最低出价。这还将在 HTML 中将其添加为 min="<em>biggest-bid</em>"
以便浏览器可以验证这一点。因此,这也可以在提交表单之前在客户端验证出价,但也会在服务器端正确验证表单。
然而,最好不要通过表单传递列表,而是作为 URL 参数。
Note: You can limit views to a view to authenticated users with the
@login_required
decorator [Django-doc].
我想确保 bid field
的当前值不小于当前最大值 bid
。这是我使用自定义 clean
方法的表单。
表格:
class Place_A_Bid_Form(forms.Form):
listing = forms.CharField(widget=forms.TextInput(attrs={"type":"hidden"}))
bid = forms.IntegerField(widget=forms.NumberInput(attrs={"class":"form-control"}), min_value=1)
def clean_bid(self, biggestBid):
bid = self.cleaned_data["bid"]
if bid < biggestBid:
raise ValidationError("""New bid shouldn't be less than starting bid, or
if any bids have been placed then new bid
should be greater than current biggest bid""")
return bid
查看:
def place_a_bid(request):
if request.method == "POST":
form = Place_A_Bid_Form(request.POST)
user = User.objects.get(username=request.user.username)
biggest_bid = Bid.objects.filter(user=user).aggregate(Max("amount"))
if form.is_valid():
data = form.cleaned_data
user_obj = User.objects.get(username=request.user.username)
listing_obj = Listing.objects.get(title=data["listing"])
Bid.objects.update_or_create(
user=user_obj,
listing=listing_obj,
amount=data["bid"]
)
return redirect(listing_obj)
鉴于我正在提取要与之比较的当前值,但我不知道如何将此值传递给我的表单字段的 clean
方法。或者也许我做错了?那么如何正确地进行这种验证呢?
class Place_A_Bid_Form(forms.Form):
listing = forms.CharField(widget=forms.TextInput(attrs={"type":"hidden"}))
bid = forms.IntegerField(widget=forms.NumberInput(attrs={"class":"form-control"}),
min_value=1)
def __init__(self,biggestBid=0 *args, **kwargs):
super().__init__(*args, **kwargs)
self.biggestBid = biggestBid
def clean_bid(self):
bid = self.cleaned_data["bid"]
if bid < self.biggestBid:
raise ValidationError("""New bid shouldn't be less than starting bid, or
if any bids have been placed then new bid
should be greater than current biggest bid""")
return bid
然后在 views.py:
def place_a_bid(request):
if request.method == "POST":
dict = Bid.objects.filter(user=user).aggregate(Max("amount"))
form = Place_A_Bid_Form(biggestBid=dict['amount__max'], data=request.POST)
user = User.objects.get(username=request.user.username)
if form.is_valid():
data = form.cleaned_data
user_obj = User.objects.get(username=request.user.username)
listing_obj = Listing.objects.get(title=data["listing"])
Bid.objects.update_or_create(
user=user_obj,
listing=listing_obj,
amount=data["bid"]
)
return redirect(listing_obj)
Django 的 IntegerField
[Django-doc] 可以在没有任何额外逻辑的情况下验证最小值,您可以设置 .min_value
并添加一个验证器:
from django.core.validators import MinValueValidator
class Place_A_Bid_Form(forms.Form):
listing = forms.CharField(widget=forms.TextInput(attrs={'type': 'hidden'}))
bid = forms.IntegerField(widget=forms.NumberInput(attrs={'class':'form-control'}))
def __init__(self, *args, **kwargs, min_bid=0):
super().__init__(*args, **kwargs)
bid = self.fields['bid']
min_bid += 1
bid<strong>.min_value = min_bid</strong>
bid<strong>.validators.add(MinValidator(min_bid))</strong>
那么你只需要将 min_bid
传递给表单:
from django.contrib.auth.decorators import login_required
@login_required
def place_a_bid(request):
biggest_bid = Bid.objects.filter(user=request.user).aggregate(
min_bid=Max('amount')
)['min_bid'] or 0
if request.method == 'POST':
form = Place_A_Bid_Form(request.POST<strong>, min_bid=biggest_bid</strong>)
if form.is_valid():
data = form.cleaned_data
listing_obj = Listing.objects.get(title=data['listing'])
Bid.objects.update_or_create(
user=request.user,
listing=listing_obj,
amount=data['bid']
)
return redirect(listing_obj)
else:
form = Place_A_Bid_Form(<strong>min_bid=biggest_bid</strong>)
return render(request, '<em>app_name</em>/name-of-template.html', {'form': form})
在 GET 请求的情况下,这也构建了一个表单,将最大出价作为最低出价。这还将在 HTML 中将其添加为 min="<em>biggest-bid</em>"
以便浏览器可以验证这一点。因此,这也可以在提交表单之前在客户端验证出价,但也会在服务器端正确验证表单。
然而,最好不要通过表单传递列表,而是作为 URL 参数。
Note: You can limit views to a view to authenticated users with the
@login_required
decorator [Django-doc].