GenericAPIView
는 REST framework의 APIView
클래스를 확장하여 standard list 및 detail views에 일반적으로 필요한 동작을 추가
하나 혹은 그 이상의 mixin class와 결합
하여 빌드몇몇 class attribute를 세팅
하게 된다. from django.contrib.auth.models import User
from rest_framework.generics import ListCreateAPIView
from rest_framework.permissions import IsAdminUser
from myapp.serializers import UserSerializer
class UserList(ListCreateAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
permission_classes = [IsAdminUser]
다양한 메서드를 오버라이딩해 사용
할 수도 있다.from django.contrib.auth.models import User
from rest_framework.generics import ListCreateAPIView
from rest_framework.permissions import IsAdminUser
from myapp.serializers import UserSerializer
class UserList(ListCreateAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
permission_classes = [IsAdminUser]
def list(self, request):
# Note the use of `get_queryset()` instead of `self.queryset`
queryset = self.get_queryset()
serializer = UserSerializer(queryset, many=True)
return Response(serializer.data)
.as_view()
메서드를 활용해 URLconf에 아래와 같이 필요한 부분을 포함해 작성하면 된다. path('users/', ListCreateAPIView.as_view(queryset=User.objects.all(), serializer_class=UserSerializer), name='user-list')
하단의 속성들은 view의 일반적인 동작을 컨트롤하는데 사용된다.
queryset을 세팅
하거나 get_queryset() method를 오버라이딩
해 사용해야 한다.get_queryset() method를 오버라이딩
해 사용하게 된다면serializer_class를 세팅
하거나 get_serializer_class() method를 오버라이딩
해야 한다.개별 모델 인스턴스를 조회
하는데 사용된다.pk
를 사용한다.URL keyword argument
이다. URL conf
는 해당 값에 대응하는 keyword argument를 포함해야 한다.페이징 처리가 된 리스트 형태의 결과
를 얻고자 할 때 사용해야 한다. 'rest_framework.pagination.PageNumberPagination'
를 DEFAULT_PAGINATION_CLASS
세팅의 디폴트값으로 사용하며, pagination_class와 동일한 값으로 사용된다. pagination_class=None
으로 세팅 시 해당 뷰에서는 페이징에 대한 결과를 확인할 수 없다. filter backend class
들은 queryset들을 필터링
하는데 사용된다. DEFAULT_FILTER_BACKENDS
세팅의 같은 값으로 사용된다. list view
에서 queryset을 반환할 때 사용된다. detail view
의 lookup의 기본값으로 사용된다. queryset
속성으로 명세화된 queryset이다. self.queryset
에 직접 접근하기보다 get_queryset
을 항상 사용해야 한다. def get_queryset(self):
user = self.request.user
return user.accounts.all()
generic view
가 orm 관계를 가질 경우, serializer_class
사용 시 n+1 problem
을 야기할 수 있다. select_related
와 prefetch_related
를 사용해 queryset을 최적화할 수 있다. detail view
에서 object instance를 반환할 때 사용한다. lookup_field
파라미터를 사용하는 것이 기본값이다. def get_object(self):
queryset = self.get_queryset()
filter = {}
for field in self.multiple_lookup_fields:
filter[field] = self.kwargs[field]
obj = get_object_or_404(queryset, **filter)
self.check_object_permissions(self.request, obj)
return obj
self.check_object_permissions
을 포함시킬 수 있다. get_object_or_404
lookup을 사용해 객체를 반환시킬 수 있다. def filter_queryset(self, queryset):
filter_backends = [CategoryFilter]
if 'geo_route' in self.request.query_params:
filter_backends = [GeoRouteFilter, CategoryFilter]
elif 'geo_point' in self.request.query_params:
filter_backends = [GeoPointFilter, CategoryFilter]
for backend in list(filter_backends):
queryset = backend().filter_queryset(self.request, queryset, view=self)
return queryset
serializer_class
속성을 반환하는 것을 기본값으로 한다. 서로 다른 serializer를 사용
하고 있거나 사용자의 타입에 따라 서로 다른 serializer들을 사용
하고 있다면, 다양한 동작을 제공하기 위해 오버라이딩할 수 있다. def get_serializer_class(self):
if self.request.user.is_staff:
return FullAccountSerializer
return BasicAccountSerializer
mixin class들에 의해 제공
되며, 객제의 저장과 삭제 행위를 위한 쉬운 오버라이딩을 제공한다. CreateModelMixin
을 사용한다. def perform_create(self, serializer):
serializer.save(user=self.request.user)
ValidationError()
를 사용해 추가적인 validation을 사용하는 데 사용할 수 있다. 해당 로직은 데이터베이스에 데이터를 저장하는 시점에 유용할 수 있다. def perform_create(self, serializer):
queryset = SignupRequest.objects.filter(user=self.request.user)
if queryset.exists():
raise ValidationError('You have already signed up')
serializer.save(user=self.request.user)
UpdateModelMixin
을 사용한다. def perform_update(self, serializer):
instance = serializer.save()
send_email_confirmation(user=self.request.user, modified=instance)
DestroyModelMixin
을 사용한다. GenericAPIView
를 사용하여 custom view를 작성하는 경우 호출해야 할 수도 있지만 일반적으로 다음 메소드를 오버라이딩할 필요가 없습니다.request
, view
, format
키를 포함한다. Response
object를 반환한다. None
값을 반환한다.mixin class를 생성해 사용
할 수 있다. class MultipleFieldLookupMixin:
"""
Apply this mixin to any view or viewset to get multiple field filtering
based on a `lookup_fields` attribute, instead of the default single field filtering.
"""
def get_object(self):
queryset = self.get_queryset() # Get the base queryset
queryset = self.filter_queryset(queryset) # Apply any filter backends
filter = {}
for field in self.lookup_fields:
if self.kwargs[field]: # Ignore empty fields.
filter[field] = self.kwargs[field]
obj = get_object_or_404(queryset, **filter) # Lookup the object
self.check_object_permissions(self.request, obj)
return obj
class RetrieveUserView(MultipleFieldLookupMixin, generics.RetrieveAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
lookup_fields = ['account', 'username']
프로젝트 전체에서 사용할 수 있는 자신만의 기본 view들의 세트
를 만들 수 있다.class BaseRetrieveView(MultipleFieldLookupMixin, generics.RetrieveAPIView):
pass
class BaseRetrieveUpdateDestroyView(MultipleFieldLookupMixin, generics.RetrieveUpdateDestroyAPIView):
pass