【问题标题】:Django form is_valid() fails and add_error() takes 2 positional arguments but 3 were givenDjango 表单 is_valid() 失败并且 add_error() 接受 2 个位置参数,但给出了 3 个
【发布时间】:2019-11-05 00:16:18
【问题描述】:

我正在创建带有条带订阅的新闻网站。以下代码在 is_valid() 检查中失败。但我不明白为什么:表单是否应该从 POST 数据中获取数据?

型号:

class CustomUser(models.Model):
    full_name = models.CharField(max_length=255)
    email = models.EmailField()
    stripe_id = models.CharField(max_length=255)

模型形式:

class CustomUserForm(ModelForm):

    class Meta:
        model = CustomUser
        fields = ("full_name", "email", "stripe_id")

    def add_error(self, message):
        # pylint: disable=E1101
        self._errors[NON_FIELD_ERRORS] = self.error_class([message])

查看功能:

def charge(request): 
    if request.method == 'POST':
        form = CustomUserForm(request.POST)
        if form.is_valid():
            try:
                charge = stripe.Charge.create(
                    amount=10000,
                    currency='usd',
                    description=form.cleaned_data['email'],
                    source=request.POST['stripeToken'],
                    card=form.cleaned_data['stripe_id'], 
                )

                form.save()
                return redirect('home')

            except stripe.error.CardError:
                form.add_error("The card has been declined.")
        else:
            print("Form is not valid")
    else:
        form = CustomUserForm()

    args = {}
    args.update(csrf(request))
    args['form'] = form
    args['publishable'] = settings.STRIPE_PUBLISHABLE_KEY
    args['months'] = range(1, 13)
    args['years'] = range(2013, 2038)
    args['soon'] = datetime.date.today() + datetime.timedelta(days=30)

    return render(request, 'accounts/charge.html', args)

我找到了类似的主题并尝试了很多。但是我仍然卡住了。 当我运行它时,它返回 add_error() takes 2 positional arguments but 3 were given 并突出显示此 form.is_valid() 行。 我也尝试在没有add_error 的情况下运行它,然后我发现该表单无效。 我正在使用 python3.7 和 Django 2.2.6。

【问题讨论】:

    标签: python django post


    【解决方案1】:

    您正在覆盖表单类上现有的 add_error 方法 - 您可以在此处查看源代码:https://github.com/django/django/blob/master/django/forms/forms.py#L307

    is_valid 的内部调用带有字段和错误消息的self.add_error,因此当您覆盖 add_error 以仅接收错误消息时,is_valid 中的调用将被破坏。

    我建议将您的自定义 add_error 方法重命名为不与 Form 类冲突的其他名称,或者以与内部使用相同的方式使用 add_error,将 None 传递给该字段如果您希望错误为 NON_FIELD_ERROR,如下所示:

    # change your view code to this after deleting your `add_error` method for the same result
    form.add_error(None, "The card has been declined.")
    

    【讨论】:

    • 我重命名了我的自定义 add_error,它变成了不显示 add_error 的错误。非常感谢。我仍然无法运行“if form.is_valid():”行,而是转到 else 行。是不是因为我输入表格有误?
    • 是的,确切地说,如果 request.POST 没有您在表单中指定的字段的有效值,is_valid 返回 False
    • 我终于可以成功了。赞赏!
    猜你喜欢
    • 2018-12-24
    • 2015-04-18
    • 1970-01-01
    • 2020-08-12
    • 1970-01-01
    • 2022-01-17
    • 2019-09-21
    • 2019-07-19
    • 2021-02-02
    相关资源
    最近更新 更多