Closed mmmeri closed 5 years ago
Ok, I fiddled around a bit and got to a solution on this, but with some caveats (see comments in example below). The solution is based on a class decorator which will dynamically add the desired field to the class, before constructing the class itself. Metaclasses won't work because attrs
does not support them.
I could not find a better name for the decorator than selfnested
.
Also, I do not know if this has any implications... :see_no_evil: Do you have any opinion on this?
Thanks!
import related
def selfnested(field_name, field_type):
def decorator(cls):
setattr(cls, field_name, field_type(
cls,
required=False # Needs to be false
))
return cls
return decorator
@related.mutable # Needs to be mutable
@selfnested('nodes', related.SequenceField)
class Node(object):
name = related.StringField()
original_json = '''
{
"name": "root",
"nodes": [{
"name": "childA",
"nodes": [{
"name": "childC"
}]
}, {
"name": "childB",
"nodes": [{
"name": "childD"
}]
}
]
}'''
json_dict = related.from_json(original_json)
node_data = related.to_model(Node, json_dict)
assert(node_data.nodes[0].name == 'childA')
assert(node_data.nodes[1].name == 'childB')
assert(node_data.nodes[0].nodes[0].name == 'childC')
assert(node_data.nodes[1].nodes[0].name == 'childD')
Thanks @lmNt for bringing this up. Always wanted to add self-referencing and out-of-order referencing, but wanted to handle it like the Django ORM does it, with strings instead of other tricks.
I implemented a flavor of this in a "self-reference" branch. Here is the unit test example:
Take a look and let me know if it meets your needs.
Note you need to provide a full reference to the model for it to work because I use importlib to dereference the model class from it's name.
Sorry for my late reply, I was on holiday and did not had a chance to check this out until today.
This looks great to me and works as expected :) Thank you very much for the super quick implementation of this feature.
I am trying to parse a nested JSON structure, where each mapping can hold a sequence of children of the same model/type. Since it is not possible to reference the class itself inside the class variables, I was hoping, that I can work around this by adding the class variable outside of the class definition. But somehow, this does not appear to work: See minimal "working" example at the bottom.
Is there a (preferable) way to do this?
Thanks a lot for your work on this package - I really dig it :)
Example
with the following output