Closed robvdl closed 8 months ago
I can use metaclasses for this which is a pretty popular Python library design pattern (e.g. Django uses it a bit):
class UserResource(Resource):
class Meta:
model = Use
And then there will be some metaclass magic in the Resource base class metaclass=
The issue is it requires doing a config.scan("sambal.resources")
as well so everything gets imported.
This is a gold-plated solution. A simpler solution is a simple lookup table manually maintained in the code:
LOOKUP = {
User.get_object_class(): UserResource,
Group.get_object_class(): GroupResource,
}
With the metaclass solution, this table can basically be automatically populated as it does a config.scan("sambal.resources")
and "imports everything" which invokes the metaclass logic.
Doesn't necessarily need to be done with a config.scan either, as RootFactory is already imported in src/sambal/__ini__.py
. So long that resources/__init__.py
imports each resource to bring them forward it already should execute the metaclass code at app startup, therefore populating the lookup table.
I've been playing around a bit with the idea and it is working.
But it turns out we need a model for Container, without that it cannot work. Container just inherits straight of "top":
top -> container
I've been able to put the model Container straight in the codebase for now and that keeps things moving, and I'll see if I can get it added to Samba itself.
This has been mostly done with the exception of the last part. If it can't find a matching model for the given object class:
RESOURCES.get(model.get_object_class(), Resource)
It needs to loop through the list of classes starting from the end, until it can find one.
Right now it always falls back to Resource.
Only then, can this ticket be closed.
This has been implemented in #46
Right now we are always constructing Resource for every object, and the queryset in the RootFactory constructor as well as Resource class constructor doesn't have polymorphic=True yet either.
This means everything is returned as Model and Resource and you end up missing half the fields that way.
There is UserResource class present, and there could be one for every model with specific behaviour and/or fields added.
It should use a specific Resource subclass if there is one for that model, otherwise fall back to Resource which is just for the base Model class.