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_versionファクトリによって返される内部関数は、ip_version変数にアクセスできます。フィールドのバリデーターリストのipv4_validatoror関数を使用し ます。ipv6_validator

を使用できるように、可能であればDjango1.4にアップグレードすることをお勧めしますGenericIPAddressField。バージョン1.3を使い続ける必要がある場合は、Django1.4からコードをバックポートできます。独自のバリデーターを使用する場合は、重複についてあまり心配する必要はありません。2つのバリデーターを機能させることに集中してください。

于 2012-05-31T22:33:36.310 に答える