-
Notifications
You must be signed in to change notification settings - Fork 300
-
Secenario
If there are some miss configuration in views or serializers it is hard to find out which of the registered views and depending serializers are bad configured for the resource_name attribute.
Take a look at the code:
def get_resource_type_from_serializer(serializer): json_api_meta = getattr(serializer, "JSONAPIMeta", None) meta = getattr(serializer, "Meta", None) if hasattr(json_api_meta, "resource_name"): return json_api_meta.resource_name elif hasattr(meta, "resource_name"): return meta.resource_name elif hasattr(meta, "model"): return get_resource_type_from_model(meta.model) raise AttributeError()
There will be no detail information on which serializer the AttributeError occurs.
Enhancement
- Tell the user for which serializer raises the error
def get_resource_type_from_serializer(serializer): json_api_meta = getattr(serializer, "JSONAPIMeta", None) meta = getattr(serializer, "Meta", None) if hasattr(json_api_meta, "resource_name"): return json_api_meta.resource_name elif hasattr(meta, "resource_name"): return meta.resource_name elif hasattr(meta, "model"): return get_resource_type_from_model(meta.model) raise AttributeError(f"can not detect 'resource_name' for serializer ' {serializer.__class__.__module__}'")
- Tell the user in which view the serializer was used (Maybe the miss configuration is made in the view
call the get_resource_type_from_serializer function with optional view parameter:
def get_resource_type_from_serializer(serializer, view=None): ... raise AttributeError(f"can not detect 'resource_name' for serializer ' {serializer.__class__.__module__}' used in view '{view.__class__.__module__}'")
Beta Was this translation helpful? Give feedback.
All reactions
Replies: 1 comment 4 replies
-
Thanks for the suggestion. Your first suggestion could be a quick improvement. Adding the view does not make too much sense though I think as getting resource type is not depended on the view but solely on the serializer.
All in all the calculation of resource_name or resource_type does not need to happen during Runtime but could be done in in the serializer meta class when the process starts up. This would be a slight performance improvement but a huge improvement in terms of the api as it would make the utility methods obsolete and error handling much more comprehensible as an error will be raised while creating a serializer class. If you could create an issue briefly explaining how calculation of resource name and resource type could be optimized that would be great.
Beta Was this translation helpful? Give feedback.
All reactions
-
Thanks for your answer. For now i am not familiar enough with python Metaclass constructions. If i understand you right, it could be handled like this:
class SerializerMetaclass(SerializerMetaclass): def __new__(cls, name, bases, attrs): serializer = super().__new__(cls, name, bases, attrs) if attrs.get("included_serializers", None): setattr( serializer, "included_serializers", LazySerializersDict(serializer, attrs["included_serializers"]), ) if attrs.get("related_serializers", None): setattr( serializer, "related_serializers", LazySerializersDict(serializer, attrs["related_serializers"]), ) json_api_meta = getattr(serializer, "JSONAPIMeta", None) meta = getattr(serializer, "Meta", None) if hasattr(json_api_meta, "resource_name"): setattr( serializer, "resource_name", json_api_meta.related_name, ) elif hasattr(meta, "resource_name"): setattr( serializer, "resource_name", meta.resource_name, ) elif hasattr(meta, "model"): setattr( serializer, "resource_name", get_resource_type_from_model(attrs["model"]) ) else: raise AttributeError(f"can not detect 'resource_name' for serializer ' {serializer.__class__.__module__}'") return serializer
If this is the correct way to handle it while constructing the serializer, then the function get_resource_type_from_serializer can be removed?
Beta Was this translation helpful? Give feedback.
All reactions
-
Basically this is how it could work. Note though that this example is the replacement for get_resource_type_from_serializer. There is also a method get_resource_name, be aware of the naming. I think it would also be better not to make this a public property. Django uses a _meta object to set all resolved fields calculated in their meta class. Maybe something we could follow but open for ideas. Also when this is implemented there might be some hurdles. e.g. at least once in the code a relation instead of a serializer is passed on to get_resource_type_from_serializer.
If you want feel free to work on a PR, details can then be discussed on actual code. Let me try to convert this to an issue.
Beta Was this translation helpful? Give feedback.
All reactions
-
👍 1
-
Thx - assign it to me - i will work on it on the next days.
Beta Was this translation helpful? Give feedback.
All reactions
-
I've create issue #1019 so we have an work item for this issue.
Beta Was this translation helpful? Give feedback.
All reactions
-
👍 1