PostSerializerDetail serializer를 이용해 직렬화하고, 해당 ViewSet을 router를 통해 url 매핑을 한 후 api2/post/<int:pk>(get) 엔드포인트에 request를 하면 에러가 발생합니다.
328
작성한 질문수 1
* 제가 추가한 코드는 다음과 같습니다.
# api2/urls.py router = routers.DefaultRouter() router.register(r'post', views.PostViewSet) urlpatterns = [ ... path('', include(router.urls)), ... ] # api2/views.py def get_prev_next(instance): try: prev = instance.get_previous_by_update_dt() except instance.DoesNotExist: prev = None try: next_ = instance.get_next_by_update_dt() except instance.DoesNotExist: next_ = None return prev, next_ class PostViewSet(ModelViewSet): queryset = Post.objects.all() serializer_class = PostListSerializer pagination_class = PostPageNumberPagination def get_serializer_context(self): return { 'request': None, 'format': self.format_kwarg, 'view': self } def get_queryset(self): return Post.objects.all().select_related('category').prefetch_related('tags', 'comment_set') def retrieve(self, request, *args, **kwargs): instance = self.get_object() prevInstance, nextInstance = get_prev_next(instance) commentList = instance.comment_set.all() data = { 'post': instance, 'prevPost': prevInstance, 'nextPost': nextInstance, 'commentList': commentList, } serializer = PostSerializerDetail(instance=data) return Response(serializer.data)
path('post/', views.PostViewSet.as_view(actions={
'get': 'list',
}), name='post-list'),
path('post/<int:pk>/', views.PostViewSet.as_view(actions={
'get': 'retrieve',
}), name='post-detail'),
path('post/<int:pk>/like/', views.PostViewSet.as_view(actions={
'get': 'like',
}), name='post-like'),
* 어떻게 하면 PostSerializerDetail를 통해 직렬화하고 해당 ViewSet이 router를 이용하도록 하여도 에러가 나지 않을 수 있을까요?
답변 2
1
/api2/post/2/?format=json 으로 해 볼래요. 그 차이를 알 수 있을 것입니다.
이 처리과정이 기본 로직이고,
질문 내용은, /api2/post/2/ 에 대한 응답으로 Browsable API 화면을 만드는 과정에서,
PUT/PATCH 용 폼을 보여주기 위해서, get_serializer_class() 를 호출하는 것입니다.
이 폼을 처리하는 로직은 알면 좋겠지만 그리 중요해 보이지는 않습니다만...
즉 일반적인 시리얼라이저 로직 플로우는 아닌 것 입니다.
참고하세요.
1
안녕하세요. 독자님.
에러가 나는 원인은, list/retrieve 처리에 시리얼라이저가 다르고,
상단에 있는 serializer_class=PostListSerializer 가 디폴트 시리얼라이저로 작동하기 때문입니다.
상단의 serializer_class 라인을 삭제하고, 아래 내용을 추가해 보세요.
def get_serializer_class(self):
if self.action == 'list':
return PostListSerializer
if self.action == 'retrieve':
return PostSerializerDetail
return PostSerializerDetail
0
def retrieve(self, request, *args, **kwargs):
. . .
# serializer = PostSerializerDetail(instance=data)
serializer = self.get_serializer(instance=data)
return Response(serializer.data)
이 부분도 수정이 필요하네요.
0
감사합니다! 그렇게 하니까 해결이 되네요.
그런데 주신 코드를 아래와 같이 수정하면 get_serializer_class가 총 4회에 걸쳐 실행되고, 처음 액션은 retrieve, 그 이후에는 각각 update, partial_update, update로 찍히는데요 혹시
1)어디에서 get_serializer_class가 호출되는지,
2)왜 액션이 update와 partail_update인지 설명해주실 수 있으신지요^^??
제가 작성한 코드
class PostViewSet(ModelViewSet):
queryset = Post.objects.all()
serializer_class = PostListSerializer
pagination_class = PostPageNumberPagination
def get_serializer_class(self):
if self.action == 'list':
print(self.action, 111)
return PostListSerializer
if self.action == 'retrieve':
print(self.action, 222)
return PostSerializerDetail
print(self.action, 333)
return PostSerializerDetail
def update(self, request, *args, **kwargs):
print("update working")
return super().update(request, *args, **kwargs)
def partial_update(self, request, *args, **kwargs):
print("partial working")
return super().partial_update(request, *args, **kwargs)
def get_queryset(self):
return Post.objects.all().select_related('category').prefetch_related('tags', 'comment_set')
def retrieve(self, request, *args, **kwargs):
instance = self.get_object()
prevInstance, nextInstance = get_prev_next(instance)
commentList = instance.comment_set.all()
data = {
'post': instance,
'prevPost': prevInstance,
'nextPost': nextInstance,
'commentList': commentList,
}
serializer = self.get_serializer(instance=data)
return Response(serializer.data)
def get_serializer_context(self):
return {
'request': None,
'format': self.format_kwarg,
'view': self
}
def like(self, request, *args, **kwargs):
instance = self.get_object()
instance.like += 1
instance.save()
return Response(instance.like)
코드가 실행되었을 때 찍힌 로그
retrieve working
retrieve 222
update 333
partial_update 333
update 333
블로그 첫 화면이 안 나옵니다.
0
317
3
INSTALLED_APPS 순서
0
246
1
vscode 실행안됨
0
667
3
django venv activate 하고 나서 vue 서버도 실행 해야 하나요?
0
367
2
더 공부할게있을까요
0
369
1
용어에 대해 문의 드립니다.
0
283
2
like 기능을 위한 overriding 문의
0
322
1
코드 최적화 과정
0
363
1
유저 1명이 1개의 게시글에 좋아요를 누를 경우
0
356
1
프로잭트를 생성하고 runserver하면 ModuleNotFoundError: No module named 발생해요
0
894
4
GET Method 에서 왜 Like 수를 증가시키는지 궁금합니다.
0
376
1
CSRF Token에 대한 질문입니다.
0
609
1
ModuleNotFoundError: No module named 'rest_framework django' 오류
0
3037
1
앱을 구성할 때 api 앱과 blog 앱을 나누어서 구성하는 이유가 궁금합니다ㅜ
1
472
2
to_representation() 오버라이딩 질문입니다.
0
496
3
공부 순서에 관해 질문드립니다.
0
360
1
CateTagAPIView에서 get 메소드
1
309
2
깃헙 페이지를 보고싶어요
0
230
1
디버거 관련 질문입니다.
0
277
3
가장 마지막강의 (Generic View -> ViewSet migration) 질문입니다.
0
223
1
PostCommentListAPIView(게시물 댓글 조회 api) 관련 질문
0
211
1
댓글 보기 및 삭제 api
0
279
1
post, comment crud 질문
0
228
4
CateTagSerializer 질문입니다!
3
336
3





