|
|
@@ -1,6 +1,5 @@
|
|
1
|
1
|
from django.core.exceptions import ImproperlyConfigured
|
|
2
|
2
|
from django.db.models.fields import CharField, DecimalField
|
|
3
|
|
-from django.db.models import SubfieldBase
|
|
4
|
3
|
from django.utils import six
|
|
5
|
4
|
from django.utils.translation import ugettext_lazy as _
|
|
6
|
5
|
|
|
|
@@ -13,6 +12,23 @@ from .autoslugfield import AutoSlugField
|
|
13
|
12
|
AutoSlugField = AutoSlugField
|
|
14
|
13
|
|
|
15
|
14
|
|
|
|
15
|
+# https://github.com/django/django/blob/64200c14e0072ba0ffef86da46b2ea82fd1e019a/django/db/models/fields/subclassing.py#L31-L44
|
|
|
16
|
+class Creator(object):
|
|
|
17
|
+ """
|
|
|
18
|
+ A placeholder class that provides a way to set the attribute on the model.
|
|
|
19
|
+ """
|
|
|
20
|
+ def __init__(self, field):
|
|
|
21
|
+ self.field = field
|
|
|
22
|
+
|
|
|
23
|
+ def __get__(self, obj, type=None):
|
|
|
24
|
+ if obj is None:
|
|
|
25
|
+ return self
|
|
|
26
|
+ return obj.__dict__[self.field.name]
|
|
|
27
|
+
|
|
|
28
|
+ def __set__(self, obj, value):
|
|
|
29
|
+ obj.__dict__[self.field.name] = self.field.to_python(value)
|
|
|
30
|
+
|
|
|
31
|
+
|
|
16
|
32
|
class ExtendedURLField(CharField):
|
|
17
|
33
|
description = _("URL")
|
|
18
|
34
|
|
|
|
@@ -64,7 +80,7 @@ class PositiveDecimalField(DecimalField):
|
|
64
|
80
|
return super(PositiveDecimalField, self).formfield(min_value=0)
|
|
65
|
81
|
|
|
66
|
82
|
|
|
67
|
|
-class UppercaseCharField(six.with_metaclass(SubfieldBase, CharField)):
|
|
|
83
|
+class UppercaseCharField(CharField):
|
|
68
|
84
|
"""
|
|
69
|
85
|
A simple subclass of ``django.db.models.fields.CharField`` that
|
|
70
|
86
|
restricts all text to be uppercase.
|
|
|
@@ -73,6 +89,14 @@ class UppercaseCharField(six.with_metaclass(SubfieldBase, CharField)):
|
|
73
|
89
|
https://docs.djangoproject.com/en/1.6/howto/custom-model-fields/#the-subfieldbase-metaclass # NOQA
|
|
74
|
90
|
"""
|
|
75
|
91
|
|
|
|
92
|
+ def contribute_to_class(self, cls, name, **kwargs):
|
|
|
93
|
+ super(UppercaseCharField, self).contribute_to_class(
|
|
|
94
|
+ cls, name, **kwargs)
|
|
|
95
|
+ setattr(cls, self.name, Creator(self))
|
|
|
96
|
+
|
|
|
97
|
+ def from_db_value(self, value, expression, connection, context):
|
|
|
98
|
+ return self.to_python(value)
|
|
|
99
|
+
|
|
76
|
100
|
def to_python(self, value):
|
|
77
|
101
|
val = super(UppercaseCharField, self).to_python(value)
|
|
78
|
102
|
if isinstance(val, six.string_types):
|
|
|
@@ -81,7 +105,7 @@ class UppercaseCharField(six.with_metaclass(SubfieldBase, CharField)):
|
|
81
|
105
|
return val
|
|
82
|
106
|
|
|
83
|
107
|
|
|
84
|
|
-class NullCharField(six.with_metaclass(SubfieldBase, CharField)):
|
|
|
108
|
+class NullCharField(CharField):
|
|
85
|
109
|
"""
|
|
86
|
110
|
CharField that stores '' as None and returns None as ''
|
|
87
|
111
|
Useful when using unique=True and forms. Implies null==blank==True.
|
|
|
@@ -100,6 +124,13 @@ class NullCharField(six.with_metaclass(SubfieldBase, CharField)):
|
|
100
|
124
|
kwargs['null'] = kwargs['blank'] = True
|
|
101
|
125
|
super(NullCharField, self).__init__(*args, **kwargs)
|
|
102
|
126
|
|
|
|
127
|
+ def contribute_to_class(self, cls, name, **kwargs):
|
|
|
128
|
+ super(NullCharField, self).contribute_to_class(cls, name, **kwargs)
|
|
|
129
|
+ setattr(cls, self.name, Creator(self))
|
|
|
130
|
+
|
|
|
131
|
+ def from_db_value(self, value, expression, connection, context):
|
|
|
132
|
+ return self.to_python(value)
|
|
|
133
|
+
|
|
103
|
134
|
def to_python(self, value):
|
|
104
|
135
|
val = super(NullCharField, self).to_python(value)
|
|
105
|
136
|
return val if val is not None else u''
|
|
|
@@ -118,7 +149,7 @@ class NullCharField(six.with_metaclass(SubfieldBase, CharField)):
|
|
118
|
149
|
return name, path, args, kwargs
|
|
119
|
150
|
|
|
120
|
151
|
|
|
121
|
|
-class PhoneNumberField(six.with_metaclass(SubfieldBase, CharField)):
|
|
|
152
|
+class PhoneNumberField(CharField):
|
|
122
|
153
|
"""
|
|
123
|
154
|
An international phone number.
|
|
124
|
155
|
|
|
|
@@ -149,6 +180,13 @@ class PhoneNumberField(six.with_metaclass(SubfieldBase, CharField)):
|
|
149
|
180
|
kwargs['max_length'] = kwargs.get('max_length', 128)
|
|
150
|
181
|
super(PhoneNumberField, self).__init__(*args, **kwargs)
|
|
151
|
182
|
|
|
|
183
|
+ def contribute_to_class(self, cls, name, **kwargs):
|
|
|
184
|
+ super(PhoneNumberField, self).contribute_to_class(cls, name, **kwargs)
|
|
|
185
|
+ setattr(cls, self.name, Creator(self))
|
|
|
186
|
+
|
|
|
187
|
+ def from_db_value(self, value, expression, connection, context):
|
|
|
188
|
+ return self.to_python(value)
|
|
|
189
|
+
|
|
152
|
190
|
def get_prep_value(self, value):
|
|
153
|
191
|
"""
|
|
154
|
192
|
Returns field's value prepared for saving into a database.
|