Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

hard debugging on resource_name missconfiguration #1017

jokiefer started this conversation in Ideas
Discussion options

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

  1. 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__}'")
  1. 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__}'") 
You must be logged in to vote

Replies: 1 comment 4 replies

Comment options

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.

You must be logged in to vote
4 replies
Comment options

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?

Comment options

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.

Comment options

Thx - assign it to me - i will work on it on the next days.

Comment options

I've create issue #1019 so we have an work item for this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Category
Ideas
Labels
None yet
2 participants

AltStyle によって変換されたページ (->オリジナル) /