from django.db import models
from django.contrib import admin
from django.forms import ValidationError as FormValidationError
from django.core.exceptions import ValidationError
from django.forms import fields, widgets
from decimal import Decimal
from IPy import IP
class IPAddressFormField(fields.Field):
default_error_messages = {
'invalid': u'Enter a valid IPv4 or IPv6 address.',
}
def clean(self, value):
'Method for validating IPs on forms'
if value in fields.EMPTY_VALUES:
return u''
try:
IP(value)
except Exception, e:
raise FormValidationError(self.error_messages['invalid'])
return super(IPAddressFormField, self).clean(value)
class IPAddressWidget(widgets.TextInput):
def render(self, name, value, attrs=None):
if isinstance(value, IP):
value = value.strNormal()
return super(IPAddressWidget, self).render(name, value, attrs)
class IPAddressField(models.Field):
__metaclass__ = models.SubfieldBase
def db_type(self):
return 'inet'
def to_python(self, value):
if not value or ((isinstance(value, str) or isinstance(value, unicode)) and value == ''):
return None
try:
value = IP(value)
except Exception, e:
raise ValidationError(e)
return value
def get_db_prep_value(self, value):
if not value:
return None
else:
return unicode(value)
def formfield(self, **kwargs):
defaults = {
'form_class': IPAddressFormField,
'widget': IPAddressWidget
}
defaults.update(kwargs)
return super(IPAddressField, self).formfield(**defaults)
Comments
I don't like error message: 'Enter a valid IPv4 or IPv6 address.'. Is is so ambiguous :-/ In my snippet no.1381, the form validation error uses a message returned by IPy.
#