I wanted to store ipv4 and ipv6 ip's in django but I wanted to use the postgresql inet network field type:
http://www.postgresql.org/docs/8.3/static/datatype-net-types.html
and I wanted to use IPy.py IP objects in python. I followed these very helpful examples along with the django documentation:
http://vaig.be/2009/03/numeric-ip-field-for-django.html http://www.djangosnippets.org/snippets/1381/
It took me awhile to figure out how this works (not that I completely understand it now..) and figured I would share it. If anyone finds problems with this or can make it better I will definitely use it.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | 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)
|
More like this
- Template tag - list punctuation for a list of items by shapiromatron 10 months, 1 week ago
- JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 10 months, 2 weeks ago
- Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
- Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 6 months ago
- Help text hyperlinks by sa2812 1 year, 6 months ago
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.
#
Please login first before commenting.