如何管理多个 Django 表单中的错误以及为什么 len(str(int)) 无法正常工作?



我正在尝试在Django 1.5Python 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})

相关内容

  • 没有找到相关文章

最新更新