Skip to content

AttributeError in ApiView get() introduced in release 3.2.0 #821

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

Closed
p-fischer opened this issue Sep 3, 2020 · 4 comments
Closed

AttributeError in ApiView get() introduced in release 3.2.0 #821

p-fischer opened this issue Sep 3, 2020 · 4 comments

Comments

@p-fischer
Copy link

p-fischer commented Sep 3, 2020

I get a crash in this code snippet, which works in version 3.1.0:

from rest_framework import permissions, status
from rest_framework.generics import GenericAPIView
from rest_framework.response import Response

from my_serializers import MySerializer


class MyAPIView(GenericAPIView):
	permission_classes = (permissions.AllowAny,)
	serializer_class = MySerializer

	def get(self, request, **kwargs):
		data = request.query_params.copy()
		serializer = self.get_serializer(data=data)

		if serializer.is_valid():
			return Response(status=status.HTTP_204_NO_CONTENT)

		return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

The partial stack trace is

 File "/path_to_my_project/views/my_view.py", line 14, in get
    serializer = self.get_serializer(data=data)
  File "/path_to_my_virtualenv/lib/python3.5/site-packages/rest_framework/generics.py", line 110, in get_serializer
    return serializer_class(*args, **kwargs)
  File "/path_to_my_virtualenv/lib/python3.5/site-packages/rest_framework_json_api/serializers.py", line 118, in __init__
    super(IncludedResourcesValidationMixin, self).__init__(*args, **kwargs)
  File "/path_to_my_virtualenv/lib/python3.5/site-packages/rest_framework_json_api/serializers.py", line 67, in __init__
    get_resource_type_from_serializer(self)
  File "/path_to_my_virtualenv/lib/python3.5/site-packages/rest_framework_json_api/utils.py", line 240, in get_resource_type_from_serializer
    raise AttributeError()
AttributeError

I run into the same error on a POST request in a different area.

Looking at the changelog and commits between 3.1.0 and 3.2.0 and suspect this commit could be related:
ff0f93a

Is this an error in the library?
Am I doing something wrong, which used to be masked before?

@sliverc
Copy link
Member

sliverc commented Sep 3, 2020

As I interpret it the former error masked another error in the DJA code base in the SparseFieldsetsMixin mixin. This should actually only be evaluated when rendering and not when parsing.

Anyhow it is good practice to define a resource_name in your serializer Meta class which should fix this issue for you (resource name is the type attribute you use for posting the data to the endpoint). Can you confirm that this works for you?

@p-fischer
Copy link
Author

Hi @sliverc thanks for your quick answer!

Sorry, I don't yet understand how to add resource_name in the serializer.
I only found this documentation https://django-rest-framework-json-api.readthedocs.io/en/stable/usage.html?highlight=resource_name#setting-the-resource-name showing examples, where resource_name is added in APIView or in the model.

My understanding of the role of resource_name is that one can overwrite the model's name in JSON API.
My crashing endpoint is used during the login/registration process, where the data I'm sending (in this case it's a GET request so data is sent via query parameters) is not backed by a model - it's just some user ID and token.
So I don't know what value is to be set for resource_name.

A couple of endpoints are crashing since the 3.2.0 update. If there is a breaking change in the library, it would be good if the change logs were extended to cover this.

@sliverc
Copy link
Member

sliverc commented Sep 4, 2020

I got mislead by your POST request statement but looking at your example it is a GET request.

I think I now see what happens and why this worked with 3.1.0 but not anymore with 3.2.0. In this change a Serializer class got introduced which did not exist before. This was introduced for deprecation warning but for clarity it also derives from the default serializer mixins like SparseFieldsetsMixin which leads to your error.

So before your APIView serializers were actually derived from rest_framework.serializers.Serializer through a star import in DJA. Now there are derived from the new rest_framework_json_api.serializers.Serializer. And a JSON API specification serializer needs to have a resource_name (either extracted from model or defined on serializer) as the specification demands this.

In your case though you don't want a JSON API spec end point but a simple APIView endpoint. In that case your serializers should actually be derived from rest_framework.serializers.Serializer and the error should disappear.

I agree though this was overlooked that introducing this serializer class could lead to issues. I will update the changelog accordingly.

Does this explain and work for you?

@p-fischer
Copy link
Author

Using rest_framework.serializers.Serializerresolves the issues I was having and your explanation makes absolute sense.
I didn't pay attention to the import statements before.
Thank you so much!

sliverc added a commit to sliverc/django-rest-framework-json-api that referenced this issue Sep 8, 2020
Clarify potential issue in changelog through introduction of
`rest_framework_json_api.serializers.Serializer` class.
n2ygk pushed a commit that referenced this issue Sep 8, 2020
Clarify potential issue in changelog through introduction of
`rest_framework_json_api.serializers.Serializer` class.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants