Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How can I easily skip certain attributes #70

Closed
dolfandringa opened this issue Aug 19, 2019 · 1 comment
Closed

How can I easily skip certain attributes #70

dolfandringa opened this issue Aug 19, 2019 · 1 comment
Labels
question The issue describes a question

Comments

@dolfandringa
Copy link

dolfandringa commented Aug 19, 2019

I can't easily find in the docs how I can specify some attributes of my JsonSerializable class that I don't want to be serialized to JSON.

class MyClass(JsonSerializable):
    def __init__(self):
        self.a = 1
        self.b = 2
        self.log = logging.getLogger(__name__)

In the above case, how can I make self.log get skipped, without having to modify the jsons.dumps call? I want the control of what gets included in the JSON to be with the class, not the place where dump(s/b) is called. So I don't want to have to make them private (with '_') and add strip_privates to dumps. First of all, that would require modifying all dumps calls throughout my code, and secondly, it forces me to change my datamodel, which has consequences elsewhere in the app.
Aside from this example where self.log clearly isn't serializable, and also wouldn't make sense to serialize, there may be other attributes that I want to skip as well. Is this easily possible with jsons? If so, can we add a FAQ question about it? (I'd be happy to contribute it)

@ramonhagenaars
Copy link
Owner

Hi @dolfandringa!

Apologies for the late answer, I normally respond sooner, but I couldn't.

There actually is a way you can skip specific attributes from being dumped. You can use strip_attr for that on the dump function.

Let's say you have the following code:

import logging
from jsons import JsonSerializable, dump


class MyClass(JsonSerializable):
    def __init__(self):
        self.a = 1
        self.b = 2
        self.log = logging.getLogger(__name__)


inst = MyClass()

You can then serialize inst using dump (or dumps or dumpb) while skipping some attribute(s) as follows:

res1 = dump(inst, strip_attr='log')
res2 = dump(inst, strip_attr=('log', 'a'))

Resulting in:

{'a': 1, 'b': 2}

for res1 and for res2:

{'b': 2}

Now since you are using JsonSerializable, it can be more convenient for you to use the with_dump on JsonSerializable, because - like you said - you don't want to add strip_attr to all dump calls.

class MyClass2(JsonSerializable.with_dump(strip_attr='log')):
    def __init__(self):
        self.a = 1
        self.b = 2
        self.log = logging.getLogger(__name__)

What this does, is altering JsonSerializable's dump method by providing the given parameter by default (similarly to how partials work).

Now you can simply do:

inst2 = MyClass2()
res3 = inst2.json

Resulting in:

{'a': 1, 'b': 2}

for res3.

Extra note

Be aware that by using with_dump as with with_load, the method of JsonSerializable is altered. That means that all other classes from this point that also inherit from JsonSerializable, will have the same altered method (with strip_attr='log' in this case). To avoid this, use fork=True:

class MyClass(JsonSerializable.with_dump(strip_attr='log', fork=True)):
    ...

As I'm writing this now, I'm thinking of changing the default behavior by setting fork to True by default rather than to False. I'd recommend you to use fork=True (like above) until then.

Finally

You were right that this was not properly documented. I will add strip_attr to the "Main functions" of the dump in the documentation. Maybe the with_dump deserves more attention as well in the docs, what do you think? Overall, I think that an FAQ item would be well suited and I would gladly accept your contribution! 🙂

@ramonhagenaars ramonhagenaars added the question The issue describes a question label Sep 7, 2019
@ramonhagenaars ramonhagenaars pinned this issue May 10, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question The issue describes a question
Projects
None yet
Development

No branches or pull requests

2 participants