google-code-export / dojango

Automatically exported from code.google.com/p/dojango
Other
1 stars 0 forks source link

Feature request: Omission of certain fields in models on JSON serialization #72

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
A lot of the times, I want to serialize an object, but not send all of its 
properties. This becomes cumbersome with Django models.

There should be some way to tell the serializer what fields to skip or include, 
in the same way as with the built-in Django JSON serializer.

I've made a custom hack for this - I am sure this could be solved in some more 
elegant way.

Diff on util/__init__.py:

<             # special FileField handling (they can't be json serialized)
<             if isinstance(f, ImageField) or isinstance(f, FileField):
<                 ret[f.attname] = unicode(getattr(data, f.attname))
<             else:
<                 ret[f.attname] = _any(getattr(data, f.attname))

---
>           if not (hasattr(data, 'CustomMeta') and hasattr(data.CustomMeta, 
'serialize_fields') and not f.attname in data.CustomMeta.serialize_fields):
>               # special FileField handling (they can't be json serialized)
>               if isinstance(f, ImageField) or isinstance(f, FileField):
>                   ret[f.attname] = unicode(getattr(data, f.attname))
>               else:
>                   ret[f.attname] = _any(getattr(data, f.attname))
158c159
<         add_ons = [k for k in dir(data) if k not in fields and k not in 
('delete', '_state',)]

---
>         add_ons = [k for k in dir(data) if k not in fields and k not in 
('delete', '_state',) and not (hasattr(data, 'CustomMeta') and 
hasattr(data.CustomMeta, 'serialize_fields') and not f.attname in 
data.CustomMeta.serialize_fields)]

How it's used in a model:

class MyModel(Model):
    id = CharField(max_length=24, primary_key=True)
    name = CharField(max_length=20)
    secret = CharField(max_length=20)
    class CustomMeta:
        serialize_fields = ('id', 'name')

Original issue reported on code.google.com by robert.e...@gmail.com on 28 Jan 2011 at 1:39

GoogleCodeExporter commented 9 years ago
Better working _model: 
    def _model(data):
        ret = {}
        # If we only have a model, we only want to encode the fields.
        try:
            serialize_fields = data.CustomMeta.serialize_fields
        except:
            serialize_fields = data._meta.fields

        for f in data._meta.fields:
            if f.attname in serialize_fields:
                # special FileField handling (they can't be json serialized)
                if isinstance(f, ImageField) or isinstance(f, FileField):
                    ret[f.attname] = unicode(getattr(data, f.attname))
                else:
                    ret[f.attname] = _any(getattr(data, f.attname))
        # And additionally encode arbitrary properties that had been added.
        fields = dir(data.__class__) + ret.keys()
        # ignoring _state and delete properties
        add_ons = [k for k in dir(data) if k not in fields and k not in ('delete', '_state',) and k in serialize_fields]
        for k in add_ons:
            ret[k] = _any(getattr(data, k))
        return ret

Original comment by robert.e...@gmail.com on 30 Jan 2011 at 1:56

GoogleCodeExporter commented 9 years ago
Hi Robert,

thanks for your input, but i have to say that I currently don't like your 
proposed change, because it'll mostly solve a very specific issue. Personally I 
like your proposed idea of a customizable json encoder more and I think this 
could help with much more use cases. Also in the case of your reported issue 
#70. My assumption is, that there are more custom fields that need a different 
serialization which isn't captured by the actual serializer. I would like to 
avoid that Dojango maintains a list of possible fields.

Some comments to your proposal: the CustomMeta class e.g. should be named 
something like DojangoMeta or alternatively we could ignore the metaclass and 
use dojango_serialize_fields as property on the model. It definitely should be 
explicit, that this change in your model is resulting Dojango to behave 
differently. Then it is immediately clear which component is handling this 
custom property/metaclass.

If you have some input on my proposal let me know.

Regards, Tobias

Original comment by tobias.k...@googlemail.com on 8 Feb 2011 at 12:09

GoogleCodeExporter commented 9 years ago
Hi, and thanks for the feedback.

Yeah, I totally agree on that the code I posted on this issue doesn't fit in 
Dojango - I made it as a quick hack in order to be able to progress with my own 
project and wanted to show one way it could be worked around until a better, 
more generic approach is worked out.
Personally I think it feels a lot better to have a Meta-style class on the 
model as opposed to a property. This also makes the models less polluted should 
you want to extend the models further in the future.

Regarding #70: Especially considering that mongoDB is becoming a popular 
database partner for Django, I think it's not reasonable that the serializer 
throws exceptions on standard models without writing custom serialization code. 
If Google Appengine specific code can be, I don't see  why a couple of lines 
(way less than the Google lines) for mongoDB can't be thrown in. Even if it's 
not the most beautiful thing to do, it's way better in practice than just 
leaving things the way they are.

Best regards,
Robert

Original comment by robert.e...@gmail.com on 10 Feb 2011 at 10:55