Login

SerializedObjectField

Author:
dominno
Posted:
March 7, 2010
Language:
Python
Version:
1.1
Score:
2 (after 2 ratings)

Model field that stores serialized value of model class instance and returns deserialized model instance. Example usage:

from django.db import models
import SerializedObjectField

class A(models.Model):
    object = SerializedObjectField(serialize_format='json')

class B(models.Model):
    field = models.CharField(max_length=10)

b = B(field='test')
b.save()

a = A()
a.object = b

a.save()

a = A.object.get(pk=1)
a.object
<B: B object>
a.object.__dict__
{'field': 'test', 'id': 1}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
from django.db import models
from django.conf import settings
from django.core import serializers
from django.db.models.query import QuerySet


class SerializedObjectField(models.TextField):
    '''Model field that stores serialized value of model class instance
       and returns deserialized model instance
       
       >>> from django.db import models
       >>> import SerializedObjectField
       
       >>> class A(models.Model):
               object = SerializedObjectField(serialize_format='json')
               
       >>> class B(models.Model):
               field = models.CharField(max_length=10)
       >>> b = B(field='test')
       >>> b.save()
       >>> a = A()
       >>> a.object = b
       >>> a.save()
       >>> a = A.object.get(pk=1)
       >>> a.object
       <B: B object>
       >>> a.object.__dict__
       {'field': 'test', 'id': 1}
       
    '''
    def __init__(self, serialize_format='json', *args, **kwargs):
        self.serialize_format = serialize_format
        super(SerializedObjectField, self).__init__(*args, **kwargs)
        
    def _serialize(self, value):
        if not value:
            return ''
        
        if not isinstance(value, QuerySet):
            value = [value]
            
        return serializers.serialize(self.serialize_format, value)
 
    def _deserialize(self, value):
        objs = [obj for obj in serializers.deserialize(self.serialize_format,
                                value.encode(settings.DEFAULT_CHARSET))]
        
        if len(objs) == 1:
            return objs[0].object
        else:
            return [obj.object for obj in objs]
 
    def db_type(self):
        return 'text'
 
    def pre_save(self, model_instance, add):
        value = getattr(model_instance, self.attname, None)
        return self._serialize(value)
 
    def contribute_to_class(self, cls, name):
        self.class_name = cls
        super(SerializedObjectField, self).contribute_to_class(cls, name)
        models.signals.post_init.connect(self.post_init)
 
    def post_init(self, **kwargs):
        if 'sender' in kwargs and 'instance' in kwargs:
            if kwargs['sender'] == self.class_name and \
            hasattr(kwargs['instance'], self.attname):
                value = self.value_from_object(kwargs['instance'])
                
                if value:
                    setattr(kwargs['instance'], self.attname,
                            self._deserialize(value))
                else:
                    setattr(kwargs['instance'], self.attname, None)

More like this

  1. Template tag - list punctuation for a list of items by shapiromatron 10 months, 1 week ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 10 months, 2 weeks ago
  3. Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 6 months ago
  5. Help text hyperlinks by sa2812 1 year, 6 months ago

Comments

Please login first before commenting.