python - Upgrade to django 1.7 - instance becomes unicode -
i moved django 1.2.5 1.7.0 (a long overdue upgrade) , expected alot of things broke. have been able fix alot of things having 1 major issue.
i have pickled objects stored in database. in django 1.2.5, ran below commands , below results
>>> app.foo.models import mymodel s >>> s.objects.get(id = 34567) <mymodel: foo (bar)> >>> x = s.objects.get(id = 34567) >>> x.myobject <foor.bar.my class instance @ 0x3855878> >>> y = x.myobject >>> type(y) <type 'instance'>
however on django 1.7.0 below
>>> app.foo.models import mymodel s >>> s.objects.get(id = 34567) <mymodel: foo (bar)> >>> x = s.objects.get(id = 34567) >>> x.myobject
vhjlzufuc3dlcknob2ljzqpwmjyycihkcdi2mwpnndekuydxzwjzaxrljwpwmjy0cnnnndmkkgxwmjy1cnniyshpbm9llnn1cnzletiudhjlzxn1cnzleqpucmvlqw5zd2vyq2hvawnlcnaynjykkgrwmjy3cmc0mqptj0vwyxblcickcdi2oapzzzqzcihscdi2oqpzymeoaw5vzs5zdxj2zxkylnryzwvzdxj2zxkkvhjlzufuc3dlcknob2ljzqpwmjcwcihkcdi3mqpnndekuydetibtywzhcmljb20gtw9iawxliefwccckcdi3mgpzzzqzcihscdi3mwpzymeoaw5vzs5zdxj2zxkylnryzwvzdxj2zxkkvhjlzufuc3dlcknob2ljzqpwmjc0cihkcdi3nqpnndekuydpdghlcickcdi3ngpzzzqzcihscdi3nwpzymfzzzykzzekc2cxmqpoc2c2nqpjmdekc2c5clmnmsckc2jhzzeymqphzzeyoqphzze2nqphzze3mwphzze4maphzze5mgphzzqkyxntj2n1cnjlbnrrdwvzdglvbickcdi3oapnnapzuydzzw5krw5ktwvzc2fnzsckcdi3oqpjmdekc1mny2fuu2vuzevuze1lc3nhz2uncnayodakstaxcnntj2nob2ljzvf1zxvljwpwmjgxcihscdi4mgpzyi4='
(this snippet of actual output)
>>> y = x.myobject >>> type(y) <type 'unicode'>
as such not able access instance methods. when check properties of object of 1.7,
>>> dir(y) ['__add__', '__class__', '__contains__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__getslice__', '__gt__', '__hash__', '__init__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '_formatter_field_name_split', '_formatter_parser', 'capitalize', 'center', 'count', 'decode', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'index', 'isalnum', 'isalpha', 'isdecimal', 'isdigit', 'islower', 'isnumeric', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']
here mymodel:
from django.db import models django.contrib.auth.models import user serializeddatafield import serializeddatafiel class mymodel(models.model): title = models.textfield() description = models.textfield() creator = models.foreignkey(user) created = models.datetimefield(auto_now_add = true) code = models.textfield() active = models.booleanfield(default = none) """pickled fresh survey object.""" myobject = serializeddatafield() """can pickled surveyobj changed? once survey has been activated, myobject cannot changed""" mutable = models.booleanfield(default = none) def __unicode__(self): return self.title + " (" + self.code + ")"
and here serialized data field
from django.db import models try: import cpickle pickle except: import pickle import base64 class serializeddatafield(models.textfield): """because django reason feels needed repeatedly call to_python after it's been converted not support strings.""" __metaclass__ = models.subfieldbase def to_python(self, value): if value none: return if not isinstance(value, basestring): return value try: value = pickle.loads(base64.b64decode(value)) return value except: return value def get_db_prep_save(self, value *args, **kwargs): if value none: return return base64.b64encode(pickle.dumps(value))
how can access instance methods if keep getting getting unicode object?
all text columns in django stored unicode data. if column binary data, can migrate binaryfield
(the field added in django 1.6).
for existing data, need encode binary byte string, can latin-1 (iso 8859-1) codec; unicode codepoints u+0000 through u+00ff map one-on-one latin-1 bytes:
y = x.surveyobject.encode('latin1')
the mistake then, treating binary data text; never text begin with.
Comments
Post a Comment