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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137 | from ipaddr import _IPAddrBase, IPAddress, IPNetwork
from django.forms import ValidationError as FormValidationError
from django.core.exceptions import ValidationError
from django.forms import fields, widgets
from django.db import models
class IPNetworkWidget(widgets.TextInput):
def render(self, name, value, attrs=None):
if isinstance(value, _IPAddrBase):
value = u'%s' % value
return super(IPNetworkWidget, self).render(name, value, attrs)
class IPNetworkManager(models.Manager):
use_for_related_fields = True
def __init__(self, qs_class=models.query.QuerySet):
self.queryset_class = qs_class
super(IPNetworkManager, self).__init__()
def get_query_set(self):
return self.queryset_class(self.model)
def __getattr__(self, attr, *args):
try:
return getattr(self.__class__, attr, *args)
except AttributeError:
return getattr(self.get_query_set(), attr, *args)
class IPNetworkQuerySet(models.query.QuerySet):
net = None
def network(self, key, value):
if not isinstance(value, _IPAddrBase):
value = IPNetwork(value)
self.net = (key, value)
return self
def iterator(self):
for obj in super(IPNetworkQuerySet, self).iterator():
try:
net = IPNetwork(getattr(obj, self.net[0]))
except (ValueError, TypeError):
pass
else:
if not self.net[1] in net:
continue
yield obj
@classmethod
def as_manager(cls, ManagerClass=IPNetworkManager):
return ManagerClass(cls)
class IPNetworkField(models.Field):
__metaclass__ = models.SubfieldBase
description = "IP Network Field with CIDR support"
empty_strings_allowed = False
def db_type(self, connection):
return 'varchar(45)'
def to_python(self, value):
if not value:
return None
if isinstance(value, _IPAddrBase):
return value
try:
return IPNetwork(value.encode('latin-1'))
except Exception, e:
raise ValidationError(e)
def get_prep_lookup(self, lookup_type, value):
if lookup_type == 'exact':
return self.get_prep_value(value)
elif lookup_type == 'in':
return [self.get_prep_value(v) for v in value]
else:
raise TypeError('Lookup type %r not supported.' \
% lookup_type)
def get_prep_value(self, value):
if isinstance(value, _IPAddrBase):
value = '%s' % value
return unicode(value)
def formfield(self, **kwargs):
defaults = {
'form_class' : fields.CharField,
'widget': IPNetworkWidget,
}
defaults.update(kwargs)
return super(IPNetworkField, self).formfield(**defaults)
class IPAddressField(models.Field):
__metaclass__ = models.SubfieldBase
description = "IP Address Field with IPv6 support"
def db_type(self, connection):
return 'varchar(42)'
def to_python(self, value):
if not value:
return None
if isinstance(value, _IPAddrBase):
return value
try:
return IPAddress(value.encode('latin-1'))
except Exception, e:
raise ValidationError(e)
def get_prep_lookup(self, lookup_type, value):
if lookup_type == 'exact':
return self.get_prep_value(value)
elif lookup_type == 'in':
return [self.get_prep_value(v) for v in value]
else:
raise TypeError('Lookup type %r not supported.' \
% lookup_type)
def get_prep_value(self, value):
if isinstance(value, _IPAddrBase):
value = '%s' % value
return unicode(value)
def formfield(self, **kwargs):
defaults = {
'form_class' : fields.CharField,
'widget': IPNetworkWidget,
}
defaults.update(kwargs)
return super(IPAddressField, self).formfield(**defaults)
|
Comments