我正在尝试在Django 1.5
和Python 2.7
中构建一个表单,用于管理来自以太PayPal或信用卡/借记卡的付款(这是一个虚拟项目,因此不会发生真正的付款)。我有两个问题:
- 首先,检查长度 f 卡号和CCV 不起作用。
- 其次,我在同一页面上有两个表单,我很想显示错误仅适用于实际编译的表单,忽略空的一。现在它显示了他们两个的错误,但我不知道如果可以避免的话。
这些是表格:
class PaymentFormPaypal(forms.Form):
paypal = forms.EmailField(required = True, label = 'Your PayPal address')
class PaymentFormCard(forms.Form):
card = forms.IntegerField(required = True, label = 'Your card number')
ccv = forms.IntegerField(required = True, label = 'Card secure code')
expiration = forms.DateField(required = True, label = 'Card expiration date', widget=forms.extras.MonthYearWidget)
name = forms.CharField(max_length = 30, required = True, label = 'Name of the card owner')
surname = forms.CharField(max_length = 30, required = True, label = 'Surname of the card owner')
def clean_card(self):
card = self.cleaned_data['card']
if len(str(card)) != 16:
raise forms.ValidationError("The card number must be 16 digits long")
def clean_ccv(self):
ccv = self.cleaned_data['ccv']
if len(str(ccv)) != 3:
raise forms.ValidationError("The ccv must be 3 digits long")
widgets = {
'expiration': forms.extras.MonthYearWidget(),
}
这个观点:
def payment(request, type):
if request.method == 'POST':
form1 = PaymentFormPaypal(request.POST)
form2 = PaymentFormCard(request.POST)
if form1.is_valid() or form2.is_valid():
profile = request.user.get_profile()
profile.premiumstatus = True
profile.save()
form = Search()
return render(request, 'home.html', {'form': form, 'request': request})
else:
form1=PaymentFormPaypal()
form2=PaymentFormCard()
return render(request, 'payment.html', {'form1': form1, 'form2': form2, 'request': request})
这是HTML
页面:
{% block content %}
<hr>
{% if request.user.is_authenticated %}
{% if form1.errors %}
<p style="color: red;">
Please correct the error{{ form1.errors|pluralize }} below.
</p>
{% endif %}
<p>Pay with PayPal.</p>
<form action="" method="post">
{% csrf_token %}
{{ form1.as_p }}
<input type="submit" value="Buy">
<input type="reset" value="Reset">
</form>
<p>Pay with your card.</p>
{% if form2.errors %}
<p style="color: red;">
Please correct the error{{ form2.errors|pluralize }} below.
</p>
{% endif %}
<form action="" method="post">
{% csrf_token %}
{{ form2.as_p }}
<input type="submit" value="Buy">
<input type="reset" value="Reset">
</form>
{% else %}
<p>You must be logged to make a payment!</p>
{% endif %}
<hr>
{% endblock %}
信用卡号和CCV不是整数,它们是仅包含数字的字符串。正如您已经注意到的那样,将它们视为整数会产生很多问题。举个简单的例子:
>>> str(42)
'42'
>>> str(042)
'34'
>>>
您可以使用自定义验证器来确保您只有数字,或者在表单的clean_xxx
方法中自行检查。
>>> "1234".isdigit()
True
>>> "A123".isdigit()
False
>>>
WRT/您的第二个问题:只需在每个表单中添加一个带有表单名称的隐藏字段,然后在您的视图中检查它以了解已提交的表单,即:
<p>Pay with PayPal.</p>
<form action="" method="post">
{% csrf_token %}
<input type="hidden" name="whichform" name="paypal" />
{{ form1.as_p }}
<input type="submit" value="Buy">
<input type="reset" value="Reset">
</form>
<p>Pay with your card.</p>
{% if form2.errors %}
<p style="color: red;">
Please correct the error{{ form2.errors|pluralize }} below.
</p>
{% endif %}
<form action="" method="post">
{% csrf_token %}
<input type="hidden" name="whichform" name="card" />
{{ form2.as_p }}
<input type="submit" value="Buy">
<input type="reset" value="Reset">
</form>
然后在您看来:
def payment(request, type):
if request.method == 'POST':
whichform = request.POST.get("whichform")
if whichform == "paypal":
form = form1 = PaymentFormPaypal(request.POST)
form2 = PaymentFormCard()
elif whichform == "card":
form1 = PaymentFormPaypal()
form = form2 = PaymentFormCard(request.POST)
else:
# should not happen
form1=PaymentFormPaypal()
form2=PaymentFormCard()
form = None
if form and form.is_valid():
profile = request.user.get_profile()
profile.premiumstatus = True
profile.save()
# XXX fixed this, you want to REDIRECT here
# Google for "post redirect get" for more infos
return redirect(<your home url here>)
else:
form1=PaymentFormPaypal()
form2=PaymentFormCard()
return render(request, 'payment.html', {'form1': form1, 'form2': form2, 'request': request})