gintas / django-picklefield

A pickled object field for Django
MIT License
180 stars 47 forks source link

problem subclassing and overriding from_db_value #32

Closed tisdall closed 5 years ago

tisdall commented 7 years ago

I recently upgraded from Django 1.7 to 1.8 and have run into problems with a subclassed PickledObjectField. The code looks like this:

from picklefield.fields import PickledObjectField as OriginalPickledObjectField

class PickledObjectField(OriginalPickledObjectField):
    """ Modified to return an empty `dict` object if empty """

    def to_python(self, value):
        return super(PickledObjectField, self).to_python(value) or {}

I had some spots where the field was sometimes None/NULL but wanted to treat those as equivalent to an empty dictionary. It worked fine until I upgraded to Django 1.8 .

I saw that in 1.8 it stops using the models.SubfieldBase metaclass and instead used from_db_value. I think the existing from_db_value, which calls to_python, should be fine but the field returns as None instead of an empty dict. I tried overriding the method to call my to_python, but for some reason it doesn't even get called!

I'm totally stumped as to what's going wrong.

tisdall commented 7 years ago

I think the issue is from_db_value isn't called on assignment where the old system with the metaclass caused the to_python to be called.

Are there any suggestions on how to modify my subclass such that NULL values can be treated like an empty dict?

charettes commented 5 years ago

Sorry for the delay on the reply here. It looks like Django's from_db_value introduction includes guidelines on how such a behavior can be restored.

From Django 1.8 release notes

The new approach doesn’t call the to_python() method on assignment as was the case with SubfieldBase. If you need that behavior, reimplement the Creator class from Django’s source code in your project.

I'll close this for now as this has become the de-facto behavior of model fields at this point.