1
1
import re
2
2
from IPy import IP
3
3
4
+ from django import forms
4
5
from django .db import models , connection
5
6
from django .db .models import sql , query
6
7
from django .db .models .query_utils import QueryWrapper
7
- from django import forms
8
+ from django .utils .encoding import force_unicode
9
+ from django .utils .safestring import mark_safe
8
10
9
11
NET_OPERATORS = {
10
12
'lt' : '<' ,
@@ -40,6 +42,7 @@ def add_filter(self, (filter_string, value), *args, **kwargs):
40
42
return super (NetQuery , self ).add_filter (
41
43
(filter_string , value ), * args , ** kwargs )
42
44
45
+
43
46
class NetWhere (sql .where .WhereNode ):
44
47
def make_atom (self , child , qn ):
45
48
table_alias , name , db_type , lookup_type , value_annot , params = child
@@ -78,20 +81,35 @@ def make_atom(self, child, qn):
78
81
79
82
raise ValueError ('Invalid lookup type "%s"' % lookup_type )
80
83
84
+
81
85
class NetManger (models .Manager ):
82
86
use_for_related_fields = True
83
87
84
88
def get_query_set (self ):
85
89
q = NetQuery (self .model , connection , NetWhere )
86
90
return query .QuerySet (self .model , q )
87
91
92
+
93
+ class NetInput (forms .Widget ):
94
+ input_type = 'text'
95
+
96
+ def render (self , name , value , attrs = None ):
97
+ # Default forms.Widget compares value != '' which breaks IP...
98
+ if value is None : value = ''
99
+ final_attrs = self .build_attrs (attrs , type = self .input_type , name = name )
100
+ if value :
101
+ final_attrs ['value' ] = force_unicode (value )
102
+ return mark_safe (u'<input%s />' % forms .util .flatatt (final_attrs ))
103
+
104
+
88
105
class NetAddressFormField (forms .Field ):
106
+ widget = NetInput
89
107
default_error_messages = {
90
108
'invalid' : u'Enter a valid IP Address.' ,
91
109
}
92
110
93
111
def __init__ (self , * args , ** kwargs ):
94
- super (DateTimeField , self ).__init__ (* args , ** kwargs )
112
+ super (NetAddressFormField , self ).__init__ (* args , ** kwargs )
95
113
96
114
def clean (self , value ):
97
115
super (NetAddressFormField , self ).clean (value )
@@ -102,18 +120,20 @@ def clean(self, value):
102
120
return value
103
121
try :
104
122
return IP (value )
105
- except ValueError :
106
- raise forms .ValidationError (self .error_messages ['invalid' ])
123
+ except ValueError , e :
124
+ raise forms .ValidationError (e )
125
+
107
126
108
- mac_re = re .compile (r'^(([A-F0-9]:){5}[A-F0-9])$' )
127
+ mac_re = re .compile (r'^(([A-F0-9]{2} :){5}[A-F0-9]{2} )$' )
109
128
110
129
class MACAddressFormField (forms .RegexField ):
111
130
default_error_messages = {
112
131
'invalid' : u'Enter a valid MAC address.' ,
113
132
}
114
133
115
134
def __init__ (self , * args , ** kwargs ):
116
- super (IPAddressField , self ).__init__ (mac_re , * args , ** kwargs )
135
+ super (MACAddressFormField , self ).__init__ (mac_re , * args , ** kwargs )
136
+
117
137
118
138
class _NetAddressField (models .Field ):
119
139
empty_strings_allowed = False
@@ -153,6 +173,7 @@ def formfield(self, **kwargs):
153
173
defaults .update (kwargs )
154
174
return super (_NetAddressField , self ).formfield (** defaults )
155
175
176
+
156
177
class InetAddressField (_NetAddressField ):
157
178
description = "PostgreSQL INET field"
158
179
max_length = 39
@@ -161,6 +182,7 @@ class InetAddressField(_NetAddressField):
161
182
def db_type (self ):
162
183
return 'inet'
163
184
185
+
164
186
class CidrAddressField (_NetAddressField ):
165
187
description = "PostgreSQL CIDR field"
166
188
max_length = 43
@@ -169,6 +191,7 @@ class CidrAddressField(_NetAddressField):
169
191
def db_type (self ):
170
192
return 'cidr'
171
193
194
+
172
195
class MACAddressField (models .Field ):
173
196
description = "PostgreSQL MACADDR field"
174
197
@@ -184,6 +207,8 @@ def formfield(self, **kwargs):
184
207
defaults .update (kwargs )
185
208
return super (MACAddressField , self ).formfield (** defaults )
186
209
210
+
211
+ # ---- TESTS ----
187
212
class InetTestModel (models .Model ):
188
213
'''
189
214
>>> cursor = connection.cursor()
0 commit comments