๋ฏน์ค์ธ์ด๋ ํน์ ํ ํด๋์ค์ ์์์ ํตํด ์๋ก์ด ์์ฑ์ด๋ ์๋ก์ด ๊ธฐ๋ฅ์ ์ถ๊ฐ(Mix in)ํ๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค. ์ด๋ฅผ ์ ํ์ฉํ ์คํ์์ค๊ฐ ๋ฐ๋ก Django Rest Framework
์ด๋ค. Django Rest Framework
์์๋ GenericAPIView
์ ์์ฑ, ์์ ๋ฑ์ ๋ค์ํ ๋ฏน์ค์ธ ํด๋์ค๋ฅผ ์ถ๊ฐํด ์ฝ๊ฒ API View๋ฅผ ๊ตฌํํ ์ ์๊ฒ ํด์ค๋ค.
Django Rest Framework
๊ณต์๋ฌธ์์์ ์ ๊ณตํ๋ ์์ ๋ฅผ ๋ด๋ณด๋ฉด ListModelMixin
๊ณผ CreateModelMixin
์ ์์ ๋ฐ์์ผ๋ก์จ get
๋ฉ์๋์ post
๋ฉ์๋์์ list
์ create
๋ผ๋ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ ์ ์๋ค. ์ด๋ฅผ ํตํด ๊ฐ๋ฐ์๋ค์ ๋ณธ์ธ๋ค์ด ์ํ๋ ๊ธฐ๋ฅ์ ๋ณด๋ค ์ฝ๊ณ ๊ฐํธํ๊ฒ ์ด์ฉํ ์ ์๋ค.
๐ rest_framework/mixins.py
์๋์ Class๋ค์ ์ฌ์ฉํ๊ธฐ ์ํด์๋ ๋ค์๊ณผ ๊ฐ์ด import๋ฅผ ํ์๋ก ํฉ๋๋ค.
from rest_framework.mixins import (
ListModelMixin, CreateModelMixin, UpdateModelMixin)
๐ rest_framework/viewsets.py
์๋๋ฉด viewsets ํ์ผ ๋ด ViewSet ์ข
๋ฅ๋ค ์ค ์ํ๋ ํํ๋ฅผ importํด ์ฌ์ฉํ๋ ๊ฒ๋ ๊ฐ๋ฅํฉ๋๋ค.
from rest_framework.viewsets import ModelViewSet
์ฟผ๋ฆฌ ์งํฉ ๋์ด
method : GET
์ฃผ๋ก ์ฐ๋ ํํ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
def list(request, *args, **kwargs)
์์ ์ฝ๋๋ง์ผ๋ก View๊ฐ ๋ง๋ค์ด์ง ์ ์๋ ๊ฒ์ Django์์ ์ ๊ณตํ๋ ListAPIView๋ฅผ ์์๋ฐ์๊ธฐ ๋๋ฌธ์ด๋ค.
๊ทธ๋ผ ์ด ๊ฐ๋จํ ํํ๋ฅผ ์ด๋ป๊ฒ ์ธ ์ ์๋์ง ํ ๋ฒ ์ดํด๋ด๋ณด์.
๐ rest_framework/generics.py
class ListAPIView(mixins.ListModelMixin,
GenericAPIView):
"""
Concrete view for listing a queryset.
"""
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
์ด ์ฝ๋๋ฅผ ๊ฐ๋จํ ์์ฝํ๋ฉด, ์ฌ์ฉ์๊ฐ GET ์์ฒญ์ ๋ณด๋ผ ๊ฒฝ์ฐ, list()๋ผ๋ ํจ์๋ฅผ ์คํ์ํจ๋ค๋ ๋ด์ฉ์ ๋๋ค.
๊ทธ๋ ๋ค๋ฉด list() ํจ์๋ ์ด๋จ๋์ง, ์ด๋ป๊ฒ ์๋ํ๋์ง ํ์ธํด๋ณด๋ ค๋ฉด restframework/mixins.py
์ ๊ตฌํ๋์ด ์๋ ListModelMixin class์
๋๋ค.
๐ rest_framework/mixins.py
class ListModelMixin:
"""
List a queryset.
"""
def list(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset()) # 1๋ฒ
page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data)
serializer = self.get_serializer(queryset, many=True) # 2๋ฒ
return Response(serializer.data) # 3๋ฒ
๋จผ์ ํ ์ค์ฉ ์ดํด๋ด๋ณด์. ๋จผ์ 1๋ฒ์ ์ดํด๋ณด๋ฉด
๐ 1๋ฒ
queryset = self.filter_queryset(self.get_queryset())
filter_queryset
๊ณผ get_queryset
์ ํจ์๋ช
์์ ๋ณผ ์ ์๋ฏ์ด queryset์ ๊ฐ์ ธ์จ๋ค๋ ๊ฒ์ ์ ์ ์์ต๋๋ค. ์ด query๋ ์ด๋์ ๊ฐ์ ธ์ค๋๊ฑธ๊น?
๐ view.py
class DongListView(ListAPI):
serializer_class = DongSerializer
queryset = Dong.objects.all()
ํด๋น ํด๋์ค๋ฅผ ์ฌ์ฉํ๊ณ queryset = model.objects.all()
์ ๊ฐ์ด ํธ์ถํ๊ฒ ๋๋ฉด ๋ฐฉ๊ธ ๋ณธ 1๋ฒ์ ์ฝ๋๊ฐ ์๋ํ๋ ๊ฒ์
๋๋ค.
๐ 2๋ฒ
serializer = self.get_serializer(queryset, many=True)
์ฌ๊ธฐ ์ญ์ ์์ง ๋ชปํ๋ ํจ์์ ๋ฐํ๊ฐ์ด ๋ณ์์ ๋๊ฒจ์ง๊ณ ์๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค.
get_serializer์ ์ด๋ฆ์์ ์ ์ ์๋ฏ์ด serializer๋ฅผ ๊ฐ์ ธ์ค๋ ํจ์๋ฅผ ์๋ฏธํฉ๋๋ค. ์ด ๋ํ DongListView์์ ์ ์ธํ serializer_class์ ๊ฐ์ ๊ฐ์ ธ์ค๋ ๊ฒ์ ์ ์ ์์ต๋๋ค.
ํ์ง๋ง ์ฌ๊ธฐ์ ๋ค๋ฅธ ์ ์ด ์๋๋ฐ, ๋งค๊ฐ ๋ณ์๋ฅผ ๋ฃ์ด์ค๋ค๋ ์ ์
๋๋ค. ๋งค๊ฐ ๋ณ์๋ก queryset๊ณผ many=True
๊ฐ์ด ๋ค์ด๊ฐ์๋๋ฐ, queryset์ Model์ ๋ฐ์ดํฐ๋ค์ธ ๋ฐ๋ฉด์ many=True๋ ์ด๋ค ๊ฐ์ ์๋ฏธํ ๊น์?
๋ฐ๋ก ๋งค๊ฐ ๋ณ์๋ช ์์ ์ ์ ์๋ฏ์ด ์ฌ๊ฑฐ ๊ฐ์ ๋ฐ์ดํฐ๋ค์ ์ง๋ ฌํํ๋ค๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค. iterableํ ๊ฐ์ฒด(list, dict, set...)๋ค์ ์ง๋ ฌํํ๋ค๋ ๊ฒ์ ๋๋ค.
๐ 3๋ฒ
return Response(serializer.data)
๋ง์ง๋ง ์ค์
๋๋ค! Response๋ผ๋ ํจ์์ serializre์ data๋ฅผ ๋๊ฒจ์ฃผ๊ณ ์์ต๋๋ค.
์์ฒญ(request)๊ณผ ์๋ต(response) ์ค, ์๋ฒ๋ Request๋ฅผ ๋ฐ์์ผ๋ฏ๋ก Response๋ฅผ ์ฌ์ฉ์์๊ฒ ๋๊ฒจ์ฃผ์ด์ผํฉ๋๋ค.
์ฌ์ฉ์๋ Post๋ค์ ๋ชฉ๋ก์ Response๋ก ๋ฐ๊ธฐ๋ฅผ ์ํ๊ธฐ ๋๋ฌธ์, serializer๋ฅผ ํตํด JSON ํํ๋ก ๋ฐ๋ ๋ฐ์ดํฐ๋ฅผ ๋๊ฒจ์ฃผ๋ ๊ฒ์ ๋๋ค.
๊ทธ๋ผ ์ง๊ธ๊น์ง ์์๋ณธ ๊ฒ์ ์ ๋ฆฌํด๋ณด์!
- ์ฌ์ฉ์๊ฐ URL์ GET์ผ๋ก ์์ฒญ์ ๋ณด๋์ต๋๋ค.
- URL์ ๋ผ์ฐํ ๋์ด ์คํํ๊ธฐ๋ก ์ฝ์ํ View๊ฐ ์คํ๋ฉ๋๋ค.
- View์ ์ ์ธํ queryset์ด list()์ ๋๊ฒจ์ง๊ฒ ๋ฉ๋๋ค.
- ๋๊ฒจ์ง query์ ๋ง์ฐฌ๊ฐ์ง๋ก View์์ ์ ์ธํ serializer๋ฅผ ํตํด JSON ํํ๋ก ๋ฐ๋๊ฒ๋ฉ๋๋ค.
- JSON์ผ๋ก ๋ฐ๋ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉ์์๊ฒ ์๋ต(Response)ํฉ๋๋ค.
์ ๋ชจ๋ธ ์ธ์คํด์ค ์์ฑ ๋ฐ ์ ์ฅ
method : POST
์ฃผ๋ก ์ฐ๋ ํํ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
def create(request, *args, **kwargs)
๋์ผํ๊ฒ ์์ ์ฝ๋๋ง์ผ๋ก View๊ฐ ๋ง๋ค์ด์ง ์ ์๋ ๊ฒ์ CreateAPIView๋ฅผ ์์๋ฐ์๊ธฐ ๋๋ฌธ์ด๋ค.
ํ ๋ฒ ์ดํด๋ณด์.
๐ rest_framework/generics.py
class CreateAPIView(mixins.CreateModelMixin,
GenericAPIView):
"""
Concrete view for creating a model instance.
"""
def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)
์ฌ์ฉ์๊ฐ POST
์์ฒญ์ ๋ณด๋ผ ๊ฒฝ์ฐ, create()๋ผ๋ ํจ์๋ฅผ ์คํ์ํจ๋ค๋ ๋ด์ฉ์
๋๋ค.
๊ทธ๋ ๋ค๋ฉด create() ํจ์๋ ์ด๋จ๋์ง, ์ด๋ป๊ฒ ์๋ํ๋์ง ํ์ธํด๋ณด๋ ค๋ฉด restframework/mixins.py
์ ๊ตฌํ๋์ด ์๋ CreateModelMixin Class๋ฅผ ์ดํด๋ณด๋ฉด ๋ฉ๋๋ค.
๋ค์์ restframework์ ๊ตฌํ๋์ด ์๋ CreateModelMixin class์ ๋๋ค.
class CreateModelMixin:
"""
Create a model instance.
"""
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data) # 1๋ฒ
serializer.is_valid(raise_exception=True) # 2๋ฒ
self.perform_create(serializer) # 3๋ฒ
headers = self.get_success_headers(serializer.data) # 4๋ฒ
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers) # 5๋ฒ
def perform_create(self, serializer):
serializer.save()
def get_success_headers(self, data):
try:
return {'Location': str(data[api_settings.URL_FIELD_NAME])}
except (TypeError, KeyError):
return {}
๋จผ์ ํ ์ค์ฉ ์ดํด๋ด๋ณด์. ๋จผ์ 1๋ฒ์ ์ดํด๋ณด๋ฉด
๐ 1๋ฒ
serializer = self.get_serializer(data=request.data)
get_serializer
์ ์ด๋ฆ์์ ์ ์ ์๋ฏ์ด serializer๋ฅผ ๊ฐ์ ธ์ค๋ ํจ์๋ฅผ ์๋ฏธํฉ๋๋ค. ์ด ๋ํ DongListView์์ ์ ์ธํ serializer_class์ ๊ฐ์ ๊ฐ์ ธ์ค๋ ๊ฒ์ ์ ์ ์์ต๋๋ค.
๐ 2๋ฒ
serializer.is_valid(raise_exception=True)
์ ํจ์ฑ ๊ฒ์ฌ๋ฅผ ์งํํ๋ ์ฝ๋์ ๋๋ค. ๋ง์ฝ ๊ฒ์ฌ๋ฅผ ํต๊ณผํ์ง ๋ชปํ๋ฉด ์์ธ๋ฅผ ๋ฐ์์ํต๋๋ค.
๐ 3๋ฒ
self.perform_create(serializer)
serializer๋ฅผ ์ ์ฅํ๋ ๋ถ๋ถ์ ๋๋ค.
๐ 4๋ฒ
headers = self.get_success_headers(serializer.data)
์ฑ๊ณตํ์ ๋ ์๋ต ํด์ค ํค๋ ๋ชฉ๋ก์ ํค๋์ ๋ฃ์ด์ฃผ๋ ๋ถ๋ถ์ ๋๋ค.
๐ 5๋ฒ
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
์์ ๊ณผ์ ์ด ์ํํ๊ฒ ์ ์งํ๋์๋ค๋ฉด ์๋ตํด์ฃผ๋ ๋ถ๋ถ์ ๋๋ค.
๊ธฐ์กด ๋ชจ๋ธ ์ธ์คํด์ค ๋ฐํ์ ๊ตฌํ
method : GET
์ฃผ๋ก ์ฐ๋ ํํ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
def retrieve(request, *args, **kwargs)
์์ ์ฝ๋๋ง์ผ๋ก View๊ฐ ๋ง๋ค์ด์ง ์ ์๋ ๊ฒ์ Django์์ ์ ๊ณตํ๋ RetrieveAPIView๋ฅผ ์์๋ฐ์๊ธฐ ๋๋ฌธ์ด๋ค.
๊ทธ๋ผ ์ด ๊ฐ๋จํ ํํ๋ฅผ ์ด๋ป๊ฒ ์ธ ์ ์์๊น?
๐ rest_framework/generics.py
class RetrieveAPIView(mixins.RetrieveModelMixin,
GenericAPIView):
"""
Concrete view for retrieving a model instance.
"""
def get(self, request, *args, **kwargs):
return self.retrieve(request, *args, **kwargs)
์ฌ์ฉ์๊ฐ GET
์์ฒญ์ ๋ณด๋ผ ๊ฒฝ์ฐ, retrieve()๋ผ๋ ํจ์๋ฅผ ์คํ์ํจ๋ค๋ ๋ด์ฉ์
๋๋ค.
๊ทธ๋ ๋ค๋ฉด retrieve() ํจ์๋ ์ด๋จ๋์ง, ์ด๋ป๊ฒ ์๋ํ๋์ง ํ์ธํด๋ณด๋ ค๋ฉด ์๋๋ฅผ ์ฐธ๊ณ ํ๋ฉด ๋ฉ๋๋ค.
๋ค์์ restframework์ ๊ตฌํ๋์ด ์๋ RetrieveModelMixin class์ ๋๋ค.
class RetrieveModelMixin:
"""
Retrieve a model instance.
"""
def retrieve(self, request, *args, **kwargs):
instance = self.get_object() # 1๋ฒ
serializer = self.get_serializer(instance) # 2๋ฒ
return Response(serializer.data) # 3๋ฒ
# get_object ์์ค ์ฝ๋
def get_object(self, queryset=None):
"""
Returns the object the view is displaying.
By default this requires `self.queryset` and a `pk` or `slug` argument
in the URLconf, but subclasses can override this to return any object.
"""
# Use a custom queryset if provided; this is required for subclasses
# like DateDetailView
if queryset is None:
queryset = self.get_queryset()
# Next, try looking up by primary key.
pk = self.kwargs.get(self.pk_url_kwarg, None)
slug = self.kwargs.get(self.slug_url_kwarg, None)
if pk is not None:
queryset = queryset.filter(pk=pk)
# Next, try looking up by slug.
if slug is not None and (pk is None or self.query_pk_and_slug):
slug_field = self.get_slug_field()
queryset = queryset.filter(**{slug_field: slug})
# If none of those are defined, it's an error.
if pk is None and slug is None:
raise AttributeError("Generic detail view %s must be called with "
"either an object pk or a slug."
% self.__class__.__name__)
try:
# Get the single item from the filtered queryset
obj = queryset.get()
except queryset.model.DoesNotExist:
raise Http404(_("No %(verbose_name)s found matching the query") %
{'verbose_name': queryset.model._meta.verbose_name})
return obj # Model.object.get(pk=pk) ์๋ฏธ
๐ 1๋ฒ
instance = self.get_object()
์์ get_object
์์ค ์ฝ๋๋ฅผ ์ฒจ๋ถํ๋๋ฐ ์ด๋ฅผ ์ ๋ฆฌํด๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
get_object๋
- queryset๊ณผ pk๊ฐ์ ์ธ์๋ก ๋ฐ์์,
- queryset.filter(pk=pk)๋ก queryset์ ๋ฝ๊ณ ,
- obj = queryset.get()์ผ๋ก ๊ฐ์ฒด๋ง ๋ฝ์์ ๋ฆฌํดํด ์ฃผ๋ ๋ฉ์๋
=> ๊ฒฐ๊ตญ, ์ ์ฝ๋๋ Model.objects.get(pk=pk) ๋ฆฌํดํฉ๋๋ค.
๋ฐ๋ผ์ 1๋ฒ์ Model.objects.get(pk=pk)
์ instance๋ผ๋ ๋ณ์์ ๋ด์์ฃผ๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค.
๐ 2๋ฒ
get_serializer
๋ instance๋ฅผ ์ธ์๋ก ๋ฐ์์, ํด๋น ๊ฐ์ฒด์ serializeํด ์ฃผ๋ ๋ฉ์๋์
๋๋ค.
๐ 3๋ฒ
serializer.data
๋ฅผ ๋ฐํํฉ๋๋ค.
๊ธฐ์กด ๋ชจ๋ธ ์ธ์คํด์ค ์ ๋ฐ์ดํธ ๋ฐ ์ ์ฅ ๊ตฌํ
method : PUT
์ฃผ๋ก ์ฐ๋ ํํ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
def update(request, *args, **kwargs)
๊ทธ๋ผ ์ด ๊ฐ๋จํ ํํ๋ฅผ ์ด๋ป๊ฒ ์ธ ์ ์์๊น?
class UpdateAPIView(mixins.UpdateModelMixin,
GenericAPIView):
"""
Concrete view for updating a model instance.
"""
def put(self, request, *args, **kwargs):
return self.update(request, *args, **kwargs)
def patch(self, request, *args, **kwargs):
return self.partial_update(request, *args, **kwargs)
์ฌ์ฉ์๊ฐ PUT
์์ฒญ์ ๋ณด๋ผ ์, update() ํจ์๋ฅผ ์คํ์ํค๊ณ , patch
์์ฒญ์ ๋ณด๋ผ ์ partial_update() ํจ์๋ฅผ ์คํ์ํต๋๋ค.
๋ค์์ restframework์ ๊ตฌํ๋์ด ์๋ UpdateModelMixin class์ ๋๋ค.
class UpdateModelMixin:
"""
Update a model instance.
"""
def update(self, request, *args, **kwargs):
partial = kwargs.pop('partial', False) # 1๋ฒ
instance = self.get_object() # 2๋ฒ
serializer = self.get_serializer(instance, data=request.data, partial=partial) # 3๋ฒ
serializer.is_valid(raise_exception=True) # 4๋ฒ
self.perform_update(serializer) # 5๋ฒ
if getattr(instance, '_prefetched_objects_cache', None):
# If 'prefetch_related' has been applied to a queryset, we need to
# forcibly invalidate the prefetch cache on the instance.
instance._prefetched_objects_cache = {}
return Response(serializer.data)
def perform_update(self, serializer):
serializer.save()
def partial_update(self, request, *args, **kwargs):
kwargs['partial'] = True
return self.update(request, *args, **kwargs)
๐ 1๋ฒ
pop ๋ฉ์๋๋ก ๋์
๋๋ฆฌ ๋ด์ partial
๋ผ๋ ํค์๋ ์ธ์๋ฅผ ๊บผ๋ด์ค๋๋ค. ๋ง์ฝ ์๋ค๋ฉด ๋ฉ์๋์ ๋ ๋ฒ์งธ ์ธ์๋ก ์ง์ ํด์ฃผ๋ฉด ๋ฉ๋๋ค.
๐ 2๋ฒ
Model.objects.get(pk=pk)
์ instance๋ผ๋ ๋ณ์์ ๋ด์์ฃผ๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค.
๐ 3๋ฒ
get_serializer๋ instance๋ฅผ ์ธ์๋ก ๋ฐ์์, ํด๋น ๊ฐ์ฒด์ serializeํด ์ฃผ๋ ๋ฉ์๋์
๋๋ค.
๐ 4๋ฒ
์ ํจ์ฑ ๊ฒ์ฌ๋ฅผ ์งํํ๋ ์ฝ๋์
๋๋ค. ๋ง์ฝ ๊ฒ์ฌ๋ฅผ ํต๊ณผํ์ง ๋ชปํ๋ฉด ์์ธ๋ฅผ ๋ฐ์์ํต๋๋ค.
๐ 5๋ฒ
์๋ perform_update
ํจ์๊ฐ ๋ณ๋๋ก ์กด์ฌํฉ๋๋ค. ํด๋น ํจ์๋ serializer์ ๊ฐ์ ์ ์ฅํ๋ ๋ฉ์๋์
๋๋ค.
๊ธฐ์กด ๋ชจ๋ธ ์ธ์คํด์ค์ ์ญ์ ๊ตฌํ
method : DELETE
์ฃผ๋ก ์ฐ๋ ํํ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
def destory(request, *args, **kwargs)
๊ทธ๋ผ ์ด ๊ฐ๋จํ ํํ๋ฅผ ์ด๋ป๊ฒ ์ธ ์ ์์๊น?
class DestroyAPIView(mixins.DestroyModelMixin,
GenericAPIView):
"""
Concrete view for deleting a model instance.
"""
def delete(self, request, *args, **kwargs):
return self.destroy(request, *args, **kwargs)
์ฌ์ฉ์๊ฐ delete
์์ฒญ์ ๋ณด๋ผ ์, destory() ํจ์๋ฅผ ์คํ์ํต๋๋ค.
๋ค์์ restframework์ ๊ตฌํ๋์ด ์๋ DestoryModelMixin class์ ๋๋ค.
class DestroyModelMixin:
"""
Destroy a model instance.
"""
def destroy(self, request, *args, **kwargs):
instance = self.get_object() # 1๋ฒ
self.perform_destroy(instance) # 2๋ฒ
return Response(status=status.HTTP_204_NO_CONTENT)
def perform_destroy(self, instance):
instance.delete()
๐ 1๋ฒ
Model.objects.get(pk=pk)
์ instance๋ผ๋ ๋ณ์์ ๋ด์์ฃผ๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค.
๐ 2๋ฒ
Class ๋ด์ perform_destroy
๋ผ๋ ํจ์๊ฐ ์กด์ฌํฉ๋๋ค. instance์ ํด๋นํ๋ ๊ฐ์ ์ง์์ฃผ๋ ํจ์์
๋๋ค.
๐ rest_framework/generics.py
์๋์ Class๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด์๋ ๋ค์๊ณผ ๊ฐ์ด import๋ฅผ ํ์๋ก ํฉ๋๋ค.
from rest_framework.mixins import (
ListModelMixin, CreateModelMixin, UpdateModelMixin)
get_queryset
์ ๋ค์ ํน์ง๋ค์ ๊ฐ์ง๊ณ ์์ต๋๋ค.
- ๋ค์ด์ค๋ ์์ฒญ์ ๋ฐ๋ผ ๋ค๋ฅด๊ฒ ์ ์ํ ์ ์์ต๋๋ค.
- ๋ค๋ฅธ ๊ณณ์์ ์ฌ์ฉํ๋ ค๋ฉด
self.get_queryset
์ ์ด์ฉํด ์ฌ์ฉํฉ๋๋ค.- queryset์ ํ ๋ฒ๋ง ํธ์ถ๋๊ณ ํ์ ์์ฒญ๋ค์ ๋ํด์๋ ๊ฒฐ๊ณผ๊ฐ ์บ์ฑ๋ฉ๋๋ค.
!!์ฌ๊ธฐ์ ์บ์ฑ๋๋ค๋ ์๋ฏธ๋ฅผ ์ ์ดํด ๋ชปํ๊ณ ์ข ๋ ๋ค์ฌ๋ค ๋ณผ ํ์๊ฐ ์์ด๋ณด์
์ด๋ค์์ผ๋ก ์บ์ฑ๋๊ณ ์ด๋ค ๋ถ๋ถ์์ ํจ๊ณผ์ ์ธ์ง check ํ์!!
๊ทธ๋ผ queryset๊ณผ get_queryset()์ ์ฐจ์ด๋ ๋ฌด์์ผ๊น? ์์ฝํด๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
queryset์ request ๋ฐ์ ์ ํ ๋ฒ๋ง ์ฟผ๋ฆฌ์ ์ด ๋์ํ๊ณ , get_queryset()์ ๋งค request๋ง๋ค ์ฟผ๋ฆฌ๋ฅผ ๋ฐ์์ํจ๋ค. ์กฐ๊ฑด์ด ๊ฑธ๋ฆฐ ์ฟผ๋ฆฌ์ ์ ์ธ ๋๋ get_queryset()์ ์ค๋ฒ๋ผ์ด๋ฉํ์.
View ๊ตฌํ ์ ์์๋ฐ๋ ํด๋์ค์ ์ถ์ํ ์ ๋: APIView < mixins < Generics < ViewSet
- mixins : APIView์์ ์ผ๋ฐ์ ์ธ ๋ก์ง๋ค์ ์์ด์ ์ฌ์ฌ์ฉ์ฑ์ ๋์ธ ๊ฒ
- Generics : mixins ์ฌ์ฉ์ ํจํดํํด์ ์ ๋ฆฌํจ
- ViewSet : Generics๋ฅผ ํ๋ฒ ๋ ํฉ์ณ์ ์ ๋ฆฌ
์ด๋ฅผ ์ด๋ป๊ฒ view์์ ์ฐ๋ํด ์ฌ์ฉํ๋์ง๋ ์ถ๊ฐ