如何将子类化的自定义Django表单字段设置为非必填?

1 投票
1 回答
1124 浏览
提问于 2025-04-16 16:12

Django的文档(http://docs.djangoproject.com/en/dev/ref/forms/fields/)提到,只要你实现了一个clean()方法,并且它的init()方法能接受一些基本参数(比如:是否必填、标签、初始值、控件、帮助文本),你就可以创建一个django.forms.Field的子类。

我在尝试使用下面这个Django代码片段:http://djangosnippets.org/snippets/907/,想要实现一个信用卡字段,但我希望这个字段不是必填的。把required设置为false在普通字段上可以正常工作,但在这个代码片段中的子类字段上却不行。这个代码片段缺少了什么呢?(我觉得它的init()方法缺失或者没有接受Django文档中提到的基本参数,但我不太确定该怎么修复。)

举个例子,把这些自定义字段的required设置为false,表单仍然要求填写:

CC_number = CreditCardField(required=False)
CC_expiration_date = CCExpField(required=False)

这个字段不要求填写(它按预期工作):

CC_security_code = forms.IntegerField(required=False)

谢谢你的帮助!

1 个回答

1

这个方法应该可以通过修改CreditCardField里的清理方法来实现(方法的前两行):

def clean(self, value):
    if not value and not self.required:
        return value
    """Check if given CC number is valid and one of the
       card types we accept"""
    if value and (len(value) < 13 or len(value) > 16):
        raise forms.ValidationError("Please enter in a valid "+\
                "credit card number.")
    elif self.get_cc_type(value) not in ("Visa", "MasterCard",
                                             "American Express"):
        raise forms.ValidationError("Please enter in a Visa, "+\
            "Master Card, or American Express credit card number.")
    return super(CreditCardField, self).clean(value)

撰写回答