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

deserialize based on value? #75

Closed
amirotin opened this issue Apr 3, 2022 · 5 comments
Closed

deserialize based on value? #75

amirotin opened this issue Apr 3, 2022 · 5 comments

Comments

@amirotin
Copy link

amirotin commented Apr 3, 2022

Hi! I'm still playing with your amazing library. In continue of another question:

I've main dataclass:

@dataclass(slots=True)
class GameRequest(DataClassJSONMixin):
    c: int
    s: int
    d: Any
    o: str = None
    t: int = None

I've many other classes for different c value of main class and want to get them into d value. I tried to use field(metadata={"deserialize": ... }) and define custom _deserialize in SerializableType. But main problem is that i always get only dict, passed to d and i don't have any references to main class request.

using {'c': 1, 's': 2, 'o': 3, 't': 12345, 'd': {'zzz': 'aaa'}} i always get only {'zzz': 'aaa'}

@amirotin amirotin changed the title deserialize based on parent class value? deserialize based on value? Apr 3, 2022
@Fatal1ty
Copy link
Owner

Fatal1ty commented Apr 3, 2022

Hi @amirotin

I read your message several times but I couldn't figure what problem you're facing. Can you give an example of what you did, what you got and what you expected?

@amirotin
Copy link
Author

amirotin commented Apr 3, 2022

Ok :)

These are json examples

{'c': 1, 's': 11, 'o': 1, 't': 12345, 'd': {'qqq': 'some data'}}
{'c': 2, 's': 33, 'o': 2, 't': 12346, 'd': {'zzz': 'some data'}}
{'c': 3, 's': 33, 'o': 2, 't': 12347, 'd': {'xxx': 'some data'}}

I have main class

@dataclass(slots=True)
class GameRequest(DataClassJSONMixin):
    c: int
    s: int
    d: Any
    o: str = None
    t: int = None

I have request type classes

@dataclass(slots=True)
class Req1(DataClassJSONMixin):
    zzz: str


@dataclass(slots=True)
class Req2(DataClassJSONMixin):
    xxx: str

@dataclass(slots=True)
class Req3(DataClassJSONMixin):
    qqq: str

i want to get such result when i call GameRequest.from_json(json_request)

GameRequest(c=1, s=11, d=Req1(zzz='some data'), o=1, t=12345)
GameRequest(c=2, s=22, d=Req2(xxx='some data'), o=2, t=12346)
GameRequest(c=3, s=33, d=Req3(qqq='some data'), o=2, t=12347)

I've function which can return needed Req class for each value of c. deserialize options only gives me key d, but not the entire request dict d: Any = field(metadata={"deserialize": lambda v: get_req(v) })

@amirotin
Copy link
Author

amirotin commented Apr 3, 2022

I also tried to make it working in this way:

@dataclass(slots=True)
class GameRequest(DataClassDictMixin, SerializableType):
    c: int
    s: int
    d: Any
    o: str = None
    t: int = None

    def _serialize(self):
        return self.to_dict()

    @classmethod
    def _deserialize(cls, value: Dict):
        print(value)
        if value.get("c") == 1:
            return Req1.from_dict(value.get('d'))
        elif value.get("c") == 2:
            return Req2.from_dict(value.get('d'))

but looks like _deserialize works only for class params, not for class itself. Or i made something wrong?

@Fatal1ty
Copy link
Owner

Fatal1ty commented Apr 3, 2022

If the choice of the ReqX class depends on another field of GameRequest, you can use the post_deserialize hook:

@dataclass
class GameRequest(DataClassJSONMixin):
    c: int
    s: int
    d: Any
    o: str = None
    t: int = None

    @classmethod
    def __post_deserialize__(cls, obj):
        if obj.c == 1:
            obj.d = Req1.from_dict(obj.d)
        elif obj.c == 2:
            obj.d = Req2.from_dict(obj.d)
        elif obj.c == 3:
            obj.d = Req3.from_dict(obj.d)
        return obj

@amirotin
Copy link
Author

amirotin commented Apr 3, 2022

post_deserialize would be last thing on my mind
Thanks! Worked.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants