Ungenericized get_item_queryset and added tag/issue queryset fetching methods to...
[philo.git] / models / fields.py
1 from django import forms
2 from django.db import models
3 from django.utils import simplejson as json
4 from philo.forms.fields import JSONFormField
5 from philo.validators import TemplateValidator, json_validator
6
7
8 class TemplateField(models.TextField):
9         def __init__(self, allow=None, disallow=None, secure=True, *args, **kwargs):
10                 super(TemplateField, self).__init__(*args, **kwargs)
11                 self.validators.append(TemplateValidator(allow, disallow, secure))
12
13
14 class JSONDescriptor(object):
15         def __init__(self, field):
16                 self.field = field
17         
18         def __get__(self, instance, owner):
19                 if instance is None:
20                         raise AttributeError # ?
21                 
22                 if self.field.name not in instance.__dict__:
23                         json_string = getattr(instance, self.field.attname)
24                         instance.__dict__[self.field.name] = json.loads(json_string)
25                 
26                 return instance.__dict__[self.field.name]
27         
28         def __set__(self, instance, value):
29                 instance.__dict__[self.field.name] = value
30                 setattr(instance, self.field.attname, json.dumps(value))
31         
32         def __delete__(self, instance):
33                 del(instance.__dict__[self.field.name])
34                 setattr(instance, self.field.attname, json.dumps(None))
35
36
37 class JSONField(models.TextField):
38         default_validators = [json_validator]
39         
40         def get_attname(self):
41                 return "%s_json" % self.name
42         
43         def contribute_to_class(self, cls, name):
44                 super(JSONField, self).contribute_to_class(cls, name)
45                 setattr(cls, name, JSONDescriptor(self))
46                 models.signals.pre_init.connect(self.fix_init_kwarg, sender=cls)
47         
48         def fix_init_kwarg(self, sender, args, kwargs, **signal_kwargs):
49                 if self.name in kwargs:
50                         kwargs[self.attname] = json.dumps(kwargs.pop(self.name))
51         
52         def formfield(self, *args, **kwargs):
53                 kwargs["form_class"] = JSONFormField
54                 return super(JSONField, self).formfield(*args, **kwargs)
55
56
57 try:
58         from south.modelsinspector import add_introspection_rules
59 except ImportError:
60         pass
61 else:
62         add_introspection_rules([], ["^philo\.models\.fields\.TemplateField"])
63         add_introspection_rules([], ["^philo\.models\.fields\.JSONField"])