我有这样的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
这里有什么不对?
答案 0 :(得分:2)
由于validator_factory
变量的关闭,ip_version
起作用。工厂返回的内部函数可以访问ip_version
变量。你会用的
<{1}}或ipv4_validator
函数在您的字段的验证程序列表中。
如果可能,我建议升级到Django 1.4,以便您可以使用GenericIPAddressField
。如果你需要坚持使用1.3版,你可以从Django 1.4向后移植代码。如果您坚持使用自己的验证器,我不会过多担心重复,只需关注两个有效的验证器。