Reputation: 411
I am using the django rest framework modelviewset to re-turn the entire post when I request get. But after writing the code, I sent the get request and the following error appears.
Traceback (most recent call last):
File "C:\Users\kurak\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
response = get_response(request)
File "C:\Users\kurak\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\core\handlers\base.py", line 115, in _get_response
response = self.process_exception_by_middleware(e, request)
File "C:\Users\kurak\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\core\handlers\base.py", line 113, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\kurak\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "C:\Users\kurak\AppData\Local\Programs\Python\Python38-32\lib\site-packages\rest_framework\viewsets.py", line 114, in view
return self.dispatch(request, *args, **kwargs)
File "C:\Users\kurak\AppData\Local\Programs\Python\Python38-32\lib\site-packages\rest_framework\views.py", line 505, in dispatch
response = self.handle_exception(exc)
File "C:\Users\kurak\AppData\Local\Programs\Python\Python38-32\lib\site-packages\rest_framework\views.py", line 465, in handle_exception
self.raise_uncaught_exception(exc)
File "C:\Users\kurak\AppData\Local\Programs\Python\Python38-32\lib\site-packages\rest_framework\views.py", line 476, in raise_uncaught_except
ion
raise exc
File "C:\Users\kurak\AppData\Local\Programs\Python\Python38-32\lib\site-packages\rest_framework\views.py", line 502, in dispatch
response = handler(request, *args, **kwargs)
File "D:\school\대회 및 프로젝트\CoCo\feed\views.py", line 23, in list
'email': serializer.data['author_email'],
KeyError: 'author_email'
I have clearly stated this in the serializer, but I don't understand why a keyerror appears. Can you tell me what the problem is in my code? Here's my code. Thank in advance.
views.py
class CreateReadPostView (ModelViewSet) :
serializer_class = PostSerializer
permission_classes = [IsAuthenticated]
queryset = Post.objects.all()
def perform_create (self, serializer) :
serializer.save(author=self.request.user)
def list (self, request) :
serializer = self.serializer_class(data=request.data)
serializer.is_valid(raise_exception=True)
data = {
'author': {
'email': serializer.data['author_email'],
'username': serializer.data['author_username'],
'profile': serializer.data['author_profile']
},
'title': serializer.data['title'],
'text': serializer.data['text'],
'images': serializer.data['image'],
'view': serializer.data['view'],
'tag': serializer.data['tag']
}
return Response(data, status=200)
serializers.py
class PostSerializer (serializers.ModelSerializer) :
author_username = serializers.CharField(source='author.username', read_only=True)
author_email = serializers.CharField(source='author.email', read_only=True)
author_profile = serializers.ImageField(source='author.profile', read_only=True, use_url=True)
title = serializers.CharField(allow_null=True)
text = serializers.CharField(allow_null=True)
image = ImageSerializer(many=True, read_only=True)
class Meta:
model = Post
fields = [
'author_username',
'author_email',
'author_profile',
'title',
'text',
'image',
'view'
]
Upvotes: 0
Views: 67
Reputation: 6296
The problem is how you defined your list
method. Please use the default list
method in the viewset as a reference to define yours.
Specifically, you are initializing the serializer with request.data
, when there is no data in the request because it is a GET request. This is only done in the POST/PUT/PATCH requests when you want to serialize the input and create a new object with the data. Instead, you should pass in the queryset that should be serialized for output.There is KeyError because author_email is readonly and you initialized the serializer in write mode so of course, the author-email is not available.
I would advice that you instead keep the inbuilt list
method and use a nested representation in the serializers like this:
class AuthorSerializer(serializers.ModelSerializer):
class Meta:
model = Author
fields = ('username', 'email', 'profile')
class PostSerializer (serializers.ModelSerializer) :
author = AuthorSerializer(read_only=True)
title = serializers.CharField(allow_null=True)
text = serializers.CharField(allow_null=True)
image = ImageSerializer(many=True, read_only=True)
class Meta:
model = Post
fields = [
'author',
'title',
'text',
'image',
'view'
]
Then you can have a simple viewset:
class CreateReadPostView (ModelViewSet) :
serializer_class = PostSerializer
permission_classes = [IsAuthenticated]
queryset = Post.objects.all()
def perform_create (self, serializer) :
serializer.save(author=self.request.user)
To understand more about how the list
method is implemented, check the ListMixin
. It fetches the queryset, applies filters and then paginates them. These are things you ommitted in your code
Upvotes: 1