可以使用某種PickledObjectField 。
class PickledObjectField(models.Field):
__metaclass__ = models.SubfieldBase
marker_re = re.compile(r'^T\[(?P<type>\w+)\](?P<value>.*)$', re.DOTALL)
markable_types = dict((t.__name__, t) for t in (str, int, unicode))
def __init__(self, *args, **kwargs):
self.compress = kwargs.pop('compress', True)
self.protocol = kwargs.pop('protocol', 2)
kwargs.setdefault('null', True)
kwargs.setdefault('editable', False)
super(PickledObjectField, self).__init__(*args, **kwargs)
def generate_type_marked_value(self, value):
return PickledObject(u"T[%s]%s" % (type(value).__name__, value))
def read_marked_value(self, value):
m = self.marker_re.match(value)
if m:
marker = m.group('type')
value = m.group('value')
if marker in self.markable_types:
value = self.markable_types[marker](value)
return value
def get_default(self):
if self.has_default():
if callable(self.default):
return self.default()
return self.default
return super(PickledObjectField, self).get_default()
def to_python(self, value):
if value is not None:
try:
if value.startswith("T["):
value = self.read_marked_value(value)
else:
value = dbsafe_decode(value, self.compress)
except:
if isinstance(value, PickledObject):
raise
return value
def get_db_prep_value(self, value):
if value is not None and not isinstance(value, PickledObject):
if type(value).__name__ in self.markable_types and not (isinstance(value, basestring) and len(value
) > MAX_MARKABLE_STRING_LENGTH):
value = unicode(self.generate_type_marked_value(value))
else:
value = unicode(dbsafe_encode(value, self.compress))
return value
def value_to_string(self, obj):
value = self._get_val_from_obj(obj)
return self.get_db_prep_value(value)
def get_internal_type(self):
return 'TextField'
def get_db_prep_lookup(self, lookup_type, value):
if lookup_type not in ['exact', 'in', 'isnull']:
raise TypeError('Lookup type %s is not supported.' % lookup_type)
return super(PickledObjectField, self).get_db_prep_lookup(lookup_type, value)
您可以顯示方法嗎? – 2013-05-09 08:57:44