1

我有这样的Django模型:

class Host():
    ipv4 = models.ChaField(max_length=39,verbose_name=_("IPv4"), validator= [ip_validator])
    ipv6 = models.CharField(max_length=39, verbose_name=_("IPv6"), 
                        blank=True, null=True, validators= [ip_validator])

我在 utils.py 中定义了 ip_validator 方法:

 from netaddr import * 
 def ip_validator(value):
 try:
     ip_version = IPAddress(value).version()
     if ip_version !=6:
         raise ValidationError(u'%s Not a  IPv6 address' % value)
 except ValueError:
     raise ValidationError(u'%s Not a IPv6 address' % value)

它工作正常,但我必须为 IPv4 验证编写相同的方法。这似乎是冗余而不是一个好主意。是否可以为 IPv4 和 IPv6 编写通用方法。

我找到了以下示例来执行此操作,但无法理解它是如何将参数传递给验证器的:

 #!/usr/bin/env python

 class IPAddress(object):
     def __init__(self, version):
         self.version = version

 def validator_factory(ip_version):
     def validate_ip_address(ip_address):
         if ip_address.version != ip_version:
             print "Invalid! :("
         else:
             print "Valid! :D"
     return validate_ip_address

 ipv4_validator = validator_factory(4)
 ipv6_validator = validator_factory(6)

 ipv4_address = IPAddress(4)
 ipv6_address = IPAddress(6)

 ipv4_validator(ipv4_address)
 ipv4_validator(ipv6_address)
 ipv6_validator(ipv6_address)

如果它是这样做的,那么我们必须通过validator = []

更新! 在models.py中:

 class Host():
     ipv4 = models.CharField(max_length=39,verbose_name=_("IPv4 address"),
                        validators=[validator_factory(4)])

这是调用验证器的正确方法吗?在 utils.py 中:

from netaddr import *

def validator_factory(ip_version):
    def validate_ip_address(ipv4):
        if IPAddress(ipv4).version != ip_version:
           print "Invalid! :("
        else:
           print "Valid! :D"
    return validate_ip_address

这里有什么问题?

4

1 回答 1

2

由于变量validator_factory的关闭而起作用。ip_versionfactory 返回的内部函数可以访问该ip_version变量。您将在您的字段的验证器列表中使用 ipv4_validatororipv6_validator函数。

如果可能,我建议升级到 Django 1.4,以便您可以使用GenericIPAddressField. 如果您需要坚持使用 1.3 版,您可以从 Django 1.4 反向移植代码。如果您坚持使用自己的验证器,我不会过多担心重复,只需专注于让两个验证器工作即可。

于 2012-05-31T22:33:36.310 回答