Django自定义表单验证IP地址和域名

5

我只是在写表单。但是我想对 hostname 进行自定义验证。如果类型为A,则验证它是一个域名,否则如果它是type = PTR则验证它是一个IP地址。这个逻辑应该放在表单还是视图中?

RECORD_CHOICES = (
     ('A','A'),
     ('Cname','CNAME'),
     ('PTR', 'PTR'),
    )

class CacheCheck(forms.Form):
    type = forms.TypedChoiceField(choices=formfields.TYPE_CHOICES, initial='FIXED')
    record = forms.TypedChoiceField(choices=formfields.RECORD_CHOICES, initial='FIXED')
    hostname = forms.CharField(max_length=100)

    def clean(self):  
        cleaned_data = super(CacheCheck, self).clean()
        record = cleaned_data.get("record")

        if record == "PTR":
            hostname = forms.GenericIPAddressField(label=("ip address"))
        else record == "A":
            hostname = forms.RegexField(label=("hostname"), max_length=31, regex=r'[a-zA-Z0-9-_]*\.[a-zA-Z]{2,6}'

同时,传递给CacheCheck类的forms.Form是一种mixin还是子类化?
2个回答

7

为您的表单编写一个clean()方法。请参阅Django文档中有关清理和验证彼此依赖的字段的信息。

您的clean方法应该返回已清理数据字典。在清理方法内部,您不能实例化新的表单字段,但可以使用验证器。

from django.core.validators import validate_ipv46_address, RegexValidator

validate_hostname = RegexValidator(regex=r'[a-zA-Z0-9-_]*\.[a-zA-Z]{2,6}')

def clean(self):  
    cleaned_data = super(CacheCheck, self).clean()
    record = cleaned_data.get("record")
    hostname = cleaned_data.get(hostname, "")

    if record == "PTR":
        validate_ipv46_address(hostname)
    elif record == "A":
        validate_hostname(hostname)
        # todo: check length of hostname as well

    return cleaned_data

回答你的另一个问题,你的CacheCheck类是forms.Form的子类。

好的,酷!那么,如果我需要在所有表单中使用相同的“clean self”函数,您认为什么是最好的方法,以便让我能够遵循“DRY”原则呢?感谢您迄今为止提供的所有帮助... - felix001
如果您有一个模型,可以将验证放在模型的clean方法中,所有模型表单都将使用它。否则,请使用继承。创建一个带有clean方法的表单,并在需要该验证时对其进行子类化。 - Alasdair
谢谢。我还有一个问题没有解决,但我还没有在http://stackoverflow.com/questions/17105947/how-do-you-pass-a-validation-error-to-a-template-in-django中发布。 - felix001

-1

这个逻辑应该在表单还是视图中完成?

两个地方都可以。在客户端使用JavaScript进行验证,避免愚蠢的错误占用服务器资源。然后在服务器端进行验证,避免在数据库中出现坏数据。

传递给CacheCheck类的表单是一种Mixin还是子类化的形式?

这是一种子类化的形式。CacheCheck继承自表单。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接