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

时间:2013-12-24 14:07:25

标签: python django django-forms

我正在尝试在Django 1.5Python 2.7中构建一个表单来管理来自以太Paypal或信用卡/借记卡的付款(这是一个虚拟项目,因此不会发生实际付款)。 我有两个问题:

  • 首先,检查长度和卡号的条件 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 %}      

1 个答案:

答案 0 :(得分:3)

信用卡号和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})