5d03e68db35b68724cf3e0602a7b9279de06f7ea
[redakcja.git] / apps / explorer / fields.py
1 # -*- coding: utf-8 -*-
2 import datetime
3
4 from django.conf import settings
5 from django.db import models
6 from django import forms
7 from django.utils import simplejson as json
8
9
10 class JSONEncoder(json.JSONEncoder):
11     def default(self, obj):
12         if isinstance(obj, datetime.datetime):
13             return obj.strftime('%Y-%m-%dT%H:%M:%S')
14         elif isinstance(obj, datetime.date):
15             return obj.strftime('%Y-%m-%d')
16         elif isinstance(obj, datetime.time):
17             return obj.strftime('%H:%M:%S')
18         return json.JSONEncoder.default(self, obj)
19
20
21 def dumps(data):
22     return JSONEncoder().encode(data)
23
24
25 def loads(str):
26     return json.loads(str, encoding=settings.DEFAULT_CHARSET)
27
28
29 class JSONFormField(forms.CharField):
30     widget = forms.Textarea
31     
32     def clean(self, value):
33         try:
34             loads(value)
35             return value
36         except ValueError, e:
37             raise forms.ValidationError('Enter a valid JSON value. Error: %s' % e)
38
39
40 class JSONField(models.TextField):
41     def formfield(self, **kwargs):
42         defaults = {'form_class': JSONFormField}
43         defaults.update(kwargs)
44         return super(JSONField, self).formfield(**defaults)
45
46     def db_type(self):
47         return 'text'
48
49     def get_internal_type(self):
50         return 'TextField'
51
52     def contribute_to_class(self, cls, name):
53         super(JSONField, self).contribute_to_class(cls, name)
54         
55         def get_value(model_instance):
56             return loads(getattr(model_instance, self.attname, None))
57         setattr(cls, 'get_%s_value' % self.name, get_value)
58
59         def set_value(model_instance, json):
60             return setattr(model_instance, self.attname, dumps(json))
61         setattr(cls, 'set_%s_value' % self.name, set_value)
62