Pickling a django model with a binary field in cacheops

梦想的初衷 提交于 2019-12-04 16:35:45

Fixed in cacheops 2.1.1.

Using external pickling function for buffer this way:

import copy_reg
copy_reg.pickle(buffer, lambda b: (buffer, (bytes(b),)))

I managed to solve the mystery so I might as well help anyone else who might encounter it.

This issue is apparently related to a bug in the pickle module in python 2.7 that will not be fixed... http://bugs.python.org/issue8323

In a nutshell, the pickle library (when using the latest protocol) is able to pickle buffer types but not to unpickle them.

When using a BinaryField in a django model, the field type in the model instance when loaded from the DB is 'buffer' which causes the problem.

A simple workaround would be to cast the 'buffer' field into an 'str'.

As to my example, this can be easily done using a post_init signal:

class MyModel(models.Model):
    bin_data = models.BinaryField()


from django.db.models.signals import post_init

def on_model_load(sender, **kwargs):
    model_obj = kwargs.get('instance', None)
    if model_obj and model_obj.bin_data is not None:
        model_obj.bin_data = str(model_obj.bin_data)

post_init.connect(on_model_load, sender=MyModel)

The workaround will allow pickling the model instance and also fix the behavior of the django-cacheops module.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!