|
1 from django.core.exceptions import FieldError |
|
2 from django.db import models |
|
3 from django.utils import simplejson as json |
|
4 from django.utils.encoding import force_unicode |
|
5 |
|
6 |
|
7 class Small(object): |
|
8 """ |
|
9 A simple class to show that non-trivial Python objects can be used as |
|
10 attributes. |
|
11 """ |
|
12 def __init__(self, first, second): |
|
13 self.first, self.second = first, second |
|
14 |
|
15 def __unicode__(self): |
|
16 return u'%s%s' % (force_unicode(self.first), force_unicode(self.second)) |
|
17 |
|
18 def __str__(self): |
|
19 return unicode(self).encode('utf-8') |
|
20 |
|
21 class SmallField(models.Field): |
|
22 """ |
|
23 Turns the "Small" class into a Django field. Because of the similarities |
|
24 with normal character fields and the fact that Small.__unicode__ does |
|
25 something sensible, we don't need to implement a lot here. |
|
26 """ |
|
27 __metaclass__ = models.SubfieldBase |
|
28 |
|
29 def __init__(self, *args, **kwargs): |
|
30 kwargs['max_length'] = 2 |
|
31 super(SmallField, self).__init__(*args, **kwargs) |
|
32 |
|
33 def get_internal_type(self): |
|
34 return 'CharField' |
|
35 |
|
36 def to_python(self, value): |
|
37 if isinstance(value, Small): |
|
38 return value |
|
39 return Small(value[0], value[1]) |
|
40 |
|
41 def get_db_prep_save(self, value): |
|
42 return unicode(value) |
|
43 |
|
44 def get_prep_lookup(self, lookup_type, value): |
|
45 if lookup_type == 'exact': |
|
46 return force_unicode(value) |
|
47 if lookup_type == 'in': |
|
48 return [force_unicode(v) for v in value] |
|
49 if lookup_type == 'isnull': |
|
50 return [] |
|
51 raise TypeError('Invalid lookup type: %r' % lookup_type) |
|
52 |
|
53 class SmallerField(SmallField): |
|
54 pass |
|
55 |
|
56 |
|
57 class JSONField(models.TextField): |
|
58 __metaclass__ = models.SubfieldBase |
|
59 |
|
60 description = ("JSONField automatically serializes and desializes values to " |
|
61 "and from JSON.") |
|
62 |
|
63 def to_python(self, value): |
|
64 if not value: |
|
65 return None |
|
66 |
|
67 if isinstance(value, basestring): |
|
68 value = json.loads(value) |
|
69 return value |
|
70 |
|
71 def get_db_prep_save(self, value): |
|
72 if value is None: |
|
73 return None |
|
74 return json.dumps(value) |