# serializers.py
class UserSimpleSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ['id', 'email']
class ProjectSerializer(serializers.ModelSerializer):
class Meta:
model = Project
fields = '__all__'
def to_representation(self, instance):
self.fields['user'] = UserSimpleSerializer()
return super(ProjectSerializer, self).to_representation(instance)
to_representation
없을 때
to_representation
있을 때
# views.py
class ProjectViewSet(ModelViewSet):
serializer_class = ProjectSerializer
queryset = Project.objects.all()
def perform_create(self, serializer):
# print("현재 유저는 : ", self.request.user)
serializer.save(user=self.request.user)
Header
- Authorization
: Bearer <jwt토큰>
을 담아서 보낸다. (안그러면 AnonymousUser라고 오류남 => AnonymousUser는 유저 객체가 X)
# serializers.py
class ProjectSerializer(serializers.ModelSerializer):
class Meta:
model = Project
fields = '__all__'
def create(self, validated_data):
instance, check = Project.objects.get_or_create(
...
user=self.context['request'].user
)
return instance
Router는 DRF에서 URL 매핑을 편리하게 해준다. 디폴트로 다음과 같이 알아서 연결해준다.
url : /prefix/
get
: listpost
: createurl : /prefix/pk/
get
: retrieveput
: updatepatch
: partial_updatedelete
: destroyfrom django.urls import include
from .views import *
from rest_framework import routers
router = routers.DefaultRouter()
router.register('prefix1', Prefix1ViewSet)
router.register('prefix2', Prefix2ViewSet)
...
urlpatterns = [
path("", include(router.urls)),
]
이런식으로 등록하면
이렇게 뜬다.
앱이 여러개일 때 router를 사용하는게 처음이라 살짝 헤맸다.
이렇게 앱이 2개 있을 때, 나는 API root 화면에서부터 아래처럼 나오게 router를 사용하고 싶었지만
Api Root
GET /api/
HTTP 200 OK
Allow: GET, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept
{
"app1": "http://127.0.0.1:8000/api/app1/",
"app2": "http://127.0.0.1:8000/api/app2/"
}
각각 app1
, app2
로 가는 viewset 자체도 존재하지 않는데다가 그런건 api도 아니니까 그냥 불가능한거였다.
그래서 프로젝트 urls.py
에서는
# project/urls.py
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('api/app1/', include('app1.urls')),
path('api/app2/', include('app2.urls')),
]
이렇게 앱이름별로 나누고,
각각 해당 앱에서
# app1/urls.py
from rest_framework import routers
router = routers.DefaultRouter()
router.register('app1_api', App1APIViewSet)
# api/app1/
urlpatterns = [
path("", include(router.urls)),
]
# app2/urls.py
from rest_framework import routers
router = routers.DefaultRouter()
router.register('app2_api', App2APIViewSet)
# api/app2/
urlpatterns = [
path("", include(router.urls)),
]
이렇게 라우터로 나눠줘야 된다.
이런 느낌?
class DuplicateProject(APIView):
@swagger_auto_schema(
tags=['project'],
operation_summary='프로젝트 복제',
manual_parameters=[
openapi.Parameter(
'id',
openapi.IN_PATH,
description='복제할 프로젝트의 id',
required=True,
default=1,
type=openapi.TYPE_INTEGER,
)
]
)
def get(self, request, pk):
...
class ProjectViewSet(ModelViewSet):
"""
list:
프로젝트 CRUD - 프로젝트 전체 리스트
---
create:
프로젝트 CRUD - 프로젝트 생성
---
retrieve:
프로젝트 CRUD - 프로젝트 조회
---
id : 조회할 프로젝트의 아이디
update:
프로젝트 CRUD - 프로젝트 수정 (전체)
---
id : 수정할 프로젝트의 아이디
partial_update:
프로젝트 CRUD - 프로젝트 수정 (일부)
---
id : 수정할 프로젝트의 아이디
destroy:
프로젝트 CRUD - 프로젝트 삭제
---
id : 삭제할 프로젝트의 아이디
"""
permission_classes = [OnlyOwnerOrPublicRead]
serializer_class = ProjectSerializer
queryset = Project.objects.all()
엔터
하고 ---
가 중요
그리고 ---
밑에 쓰면
이렇게 나옴