Django - DRF - 뷰 최적화 어셈블리
1. 데이터베이스의 삭제와 수정을 실현한다. - 일반적인 쓰기가 최적화되지 않았다(두 개의 루트와 두 개의 보기)
1-1 두 라우팅 배포 - 연결 또는 연결 안 함
데이터 검색을 위한 1-2 Serializers
1-3 뷰 함수
2. 최적화 방식 1 - Generic APIView, List Model Mixin, Create Model Mixin...
2-1 보기 함수 + 루트 설계
2-2 보기 최적화 사고방식 - 단독 중복 코드 제시, 분류 및 방법 봉인
2-3 소스 분석
2-3-1 GenericAPIView - 뷰 최적화 베이스 클래스
2-3-2 ListModelMixin - get 데이터 목록 가져오기
2-3-3 CreateModelMixin - 객체 만들기
2-3-4 RetrieveModelMixin - 단일 객체 가져오기
2-3-5 UpdateModelMixin - 개별 객체 업데이트
2-3-6 DestroyModelMixin - 객체 삭제
3. 방식 2 - ListCreate APIView, RetrieveUpdate Destroy APIView
3-1 뷰 함수
3-2 소스 분석
3-2-1 ListCreateAPIView
3-2-2 RetrieveUpdateDestroyAPIView
3-2-3 RetrieveDestroyAPIView
3-2-4 RetrieveUpdateAPIView
4, 방식 3 - ModelViewSet 협조urls 루트(추천하지 않음)
4-1 라우팅 설계
4-2 뷰 함수
4-3 원본 코드 분석
1. 데이터베이스의 삭제와 수정을 실현한다. - 일반적인 쓰기가 최적화되지 않았다(두 개의 루트와 두 개의 보기)
1-1 두 라우팅 배포 - 연결 또는 연결 안 함
from django.conf.urls import url,include
from django.contrib import admin
from app01 import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^publish/$', views.PublishView.as_view()),
url(r'^publish/(?P\d+)', views.PublishDetailView.as_view()),
]
데이터 검색을 위한 1-2 Serializers
from rest_framework import serializers
from app01 import models
class PublishSerializers(serializers.ModelSerializer):
class Meta:
model = models.Publish
fields = '__all__'
1-3 뷰 함수
from django.shortcuts import render, HttpResponse
from rest_framework.views import APIView
from django.http import JsonResponse
from app01 import MySerializer
class PublishView(APIView):
def get(self, request):
publish_list = models.Publish.objects.all()
ser = MySerializer.PublishSerializers(publish_list, many=True)
return JsonResponse(ser.data, safe=False)
def post(self, request):
ser = MySerializer.PublishSerializers(data=request.data)
if ser.is_valid():
ser.save()
return JsonResponse(ser.data, safe=False)
else:
return JsonResponse(ser.errors, safe=False)
class PublishDetailView(APIView):
def get(self, request, pk):
publish_obj = models.Publish.objects.filter(pk=pk).first()
ser = MySerializer.PublishSerializers(publish_obj, many=False)
return JsonResponse(ser.data, safe=False)
def put(self, request, pk):
publish_obj = models.Publish.objects.filter(pk=pk).first()
ser = MySerializer.PublishSerializers(data=request.data, instance=publish_obj)
if ser.is_valid():
ser.save()
return JsonResponse(ser.data, safe=False)
else:
return JsonResponse(ser.errors, safe=False)
def delete(self, request, pk):
models.Publish.objects.filter(pk=pk).delete()
return JsonResponse("delete", safe=False)
2. 최적화 방식 1 - Generic APIView, List Model Mixin, Create Model Mixin...
요약:
'''
from django.conf.urls import url,include
from django.contrib import admin
from app01 import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^publish/$', views.PublishView.as_view()),
url(r'^publish/(?P\d+)', views.PublishDetailView.as_view()),
]
'''
from app01 import models
from app01 import MySerializer
from rest_framework.mixins import ListModelMixin, CreateModelMixin, RetrieveModelMixin, UpdateModelMixin, \
DestroyModelMixin
from rest_framework.generics import GenericAPIView
class PublishView(GenericAPIView, ListModelMixin, CreateModelMixin):
queryset = models.Publish.objects.all()
serializer_class = MySerializer.PublishSerializers
def get(self, request):
return self.list(request)
def post(self, request):
return self.create(request)
class PublishDetailView(GenericAPIView, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin):
queryset = models.Publish.objects.all()
serializer_class = MySerializer.PublishSerializers
def get(self, request, pk):
return self.retrieve(request, pk)
def put(self, request, pk):
return self.update(request, pk)
def delete(self, request, pk):
return self.destroy(request, pk)
2-2 보기 최적화 사고방식 - 단독 중복 코드 제시, 분류 및 방법 봉인
'''
from django.conf.urls import url,include
from django.contrib import admin
from app01 import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^publish/$', views.PublishView.as_view()),
url(r'^publish/(?P\d+)', views.PublishDetailView.as_view()),
]
'''
'''
, ,
'''
class List:
def list(self, request):
# queryset : Publish.objects.all(),serializers : PublishSerializers
queryset = self.queryset.all()
ser = self.serializers(queryset, many=True)
return JsonResponse(ser.data, safe=False)
class Create:
def create(self, request):
print(request.data)
ser = MySerializer.PublishSerializers(data=request.data)
if ser.is_valid():
ser.save() #
return JsonResponse(ser.data, safe=False)
else:
return JsonResponse(ser.errors, safe=False)
class Retrieve:
def retrieve(self, request, pk):
queryset = self.queryset.all()
obj = queryset.filter(pk=pk).first()
ser = self.serializers(obj, many=False)
return JsonResponse(ser.data, safe=False)
class Update:
def update(self, request, pk):
obj = self.queryset.filter(pk=pk).first()
ser = self.serializers(data=request.data, instance=obj, many=False)
if ser.is_valid():
ser.save()
return JsonResponse(ser.data, safe=False)
else:
return JsonResponse(ser.errors, safe=False)
class Destroy:
def destroy(self, request, pk):
self.queryset.filter(pk=pk).delete()
return JsonResponse("delete", safe=False)
class PublishView(APIView, List, Create):
queryset = models.Publish.objects.all()
serializers = MySerializer.PublishSerializers
def get(self, request):
return self.list(request)
def post(self, request):
#
return self.create(request)
class PublishDetailView(APIView, Retrieve, Update, Destroy):
queryset = models.Publish.objects.all()
serializers = MySerializer.PublishSerializers
def get(self, request, pk):
return self.retrieve(request, pk)
def put(self, request, pk):
return self.update(request, pk)
def delete(self, request, pk):
return self.destroy(request, pk)
2-3 소스 분석
2-3-1 GenericAPIView - 뷰 최적화 베이스 클래스
class GenericAPIView(views.APIView):
"""
Base class for all other generic views.
"""
# You'll need to either set these attributes,
# or override `get_queryset()`/`get_serializer_class()`.
# If you are overriding a view method, it is important that you call
# `get_queryset()` instead of accessing the `queryset` property directly,
# as `queryset` will get evaluated only once, and those results are cached
# for all subsequent requests.
'''
, ' get_queryset() ' / ' get_serializer_class() '。
, ' get_queryset() ' ' queryset ' ,
‘queryset’ , 。
'''
queryset = None
serializer_class = None
# If you want to use object lookups other than pk, set 'lookup_field'.
# For more complex lookup requirements override `get_object()`.
'''
pk , “lookup_field”。
, ' get_object() '。
'''
lookup_field = 'pk'
lookup_url_kwarg = None
# The filter backend classes to use for queryset filtering
# queryset
filter_backends = api_settings.DEFAULT_FILTER_BACKENDS
# The style to use for queryset pagination.
# queryset 。
pagination_class = api_settings.DEFAULT_PAGINATION_CLASS
def get_queryset(self):
"""
Get the list of items for this view.
This must be an iterable, and may be a queryset.
Defaults to using `self.queryset`.
This method should always be used rather than accessing `self.queryset`
directly, as `self.queryset` gets evaluated only once, and those results
are cached for all subsequent requests.
You may want to override this if you need to provide different
querysets depending on the incoming request.
(Eg. return a list of items that is specific to the user)
"""
assert self.queryset is not None, (
"'%s' should either include a `queryset` attribute, "
"or override the `get_queryset()` method."
% self.__class__.__name__
)
queryset = self.queryset
if isinstance(queryset, QuerySet):
# Ensure queryset is re-evaluated on each request.
queryset = queryset.all()
return queryset
def get_object(self):
"""
Returns the object the view is displaying.
You may want to override this if you need to provide non-standard
queryset lookups. Eg if objects are referenced using multiple
keyword arguments in the url conf.
"""
queryset = self.filter_queryset(self.get_queryset())
# Perform the lookup filtering.
lookup_url_kwarg = self.lookup_url_kwarg or self.lookup_field
assert lookup_url_kwarg in self.kwargs, (
'Expected view %s to be called with a URL keyword argument '
'named "%s". Fix your URL conf, or set the `.lookup_field` '
'attribute on the view correctly.' %
(self.__class__.__name__, lookup_url_kwarg)
)
filter_kwargs = {self.lookup_field: self.kwargs[lookup_url_kwarg]}
obj = get_object_or_404(queryset, **filter_kwargs)
# May raise a permission denied
self.check_object_permissions(self.request, obj)
return obj
def get_serializer(self, *args, **kwargs):
"""
Return the serializer instance that should be used for validating and
deserializing input, and for serializing output.
"""
serializer_class = self.get_serializer_class()
kwargs['context'] = self.get_serializer_context()
return serializer_class(*args, **kwargs)
def filter_queryset(self, queryset):
"""
Given a queryset, filter it with whichever filter backend is in use.
You are unlikely to want to override this method, although you may need
to call it either from a list view, or from a custom `get_object`
method if you want to apply the configured filtering backend to the
default queryset.
queryset, 。
, “get_object” ,
。 queryset。
"""
for backend in list(self.filter_backends):
queryset = backend().filter_queryset(self.request, queryset, self)
return queryset
2-3-2 ListModelMixin - get 데이터 목록 가져오기
class ListModelMixin(object):
"""
List a queryset.
"""
def list(self, request, *args, **kwargs):
# GenericAPIView filter_queryset get_queryset
# queryset
queryset = self.filter_queryset(self.get_queryset())
#
page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data)
# GenericAPIView get_serializer
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)
2-3-3 CreateModelMixin - 객체 만들기
class CreateModelMixin(object):
"""
Create a model instance.
"""
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
# perform_create
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
#
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 {}
2-3-4 RetrieveModelMixin - 단일 객체 가져오기
class RetrieveModelMixin(object):
"""
Retrieve a model instance.
"""
def retrieve(self, request, *args, **kwargs):
# GenericAPIView get_object ,
instance = self.get_object()
serializer = self.get_serializer(instance)
return Response(serializer.data)
def get_object_or_404(queryset, *filter_args, **filter_kwargs):
"""
Same as Django's standard shortcut, but make sure to also raise 404
if the filter_kwargs don't match the required types.
"""
try:
return _get_object_or_404(queryset, *filter_args, **filter_kwargs)
except (TypeError, ValueError, ValidationError):
raise Http404
2-3-5 UpdateModelMixin - 개별 객체 업데이트
class UpdateModelMixin(object):
"""
Update a model instance.
"""
def update(self, request, *args, **kwargs):
partial = kwargs.pop('partial', False)
instance = self.get_object()
serializer = self.get_serializer(instance, data=request.data, partial=partial)
serializer.is_valid(raise_exception=True)
self.perform_update(serializer)
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)
2-3-6 DestroyModelMixin - 객체 삭제
class DestroyModelMixin(object):
"""
Destroy a model instance.
"""
def destroy(self, request, *args, **kwargs):
instance = self.get_object()
self.perform_destroy(instance)
return Response(status=status.HTTP_204_NO_CONTENT)
def perform_destroy(self, instance):
instance.delete()
3. 방식 2 - ListCreate APIView, RetrieveUpdate Destroy APIView
ListCreate APIView - Generic APIView, ListModel Mixin, Create Model Mixin과 동일
Retrieve Update Destroy APIView -Generic APIView, Retrieve Model Mixin, Update Model Mixin, Destroy Model Mixin과 동일
3-1 뷰 함수
from rest_framework.generics import ListCreateAPIView, RetrieveUpdateDestroyAPIView
from app01 import MySerializer
from app01 import models
# class PublishView(GenericAPIView, ListModelMixin, CreateModelMixin):
class PublishView(ListCreateAPIView):
queryset = models.Publish.objects.all()
serializer_class = MySerializer.PublishSerializers
class PublishDetailView(RetrieveUpdateDestroyAPIView):
queryset = models.Publish.objects.all()
serializer_class = MySerializer.PublishSerializers
3-2 소스 분석
3-2-1 ListCreateAPIView
class ListCreateAPIView(mixins.ListModelMixin,
mixins.CreateModelMixin,
GenericAPIView):
"""
Concrete view for listing a queryset or creating a model instance.
"""
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)
3-2-2 RetrieveUpdateDestroyAPIView
class RetrieveUpdateDestroyAPIView(mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
GenericAPIView):
"""
Concrete view for retrieving, updating or deleting a model instance.
"""
def get(self, request, *args, **kwargs):
return self.retrieve(request, *args, **kwargs)
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)
def delete(self, request, *args, **kwargs):
return self.destroy(request, *args, **kwargs)
3-2-3 RetrieveDestroyAPIView
class RetrieveDestroyAPIView(mixins.RetrieveModelMixin,
mixins.DestroyModelMixin,
GenericAPIView):
"""
Concrete view for retrieving or deleting a model instance.
"""
def get(self, request, *args, **kwargs):
return self.retrieve(request, *args, **kwargs)
def delete(self, request, *args, **kwargs):
return self.destroy(request, *args, **kwargs)
3-2-4 RetrieveUpdateAPIView
class RetrieveUpdateAPIView(mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
GenericAPIView):
"""
Concrete view for retrieving, updating a model instance.
"""
def get(self, request, *args, **kwargs):
return self.retrieve(request, *args, **kwargs)
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)
4, 방식 3 - ModelViewSet 협조urls 루트(추천하지 않음)
4-1 라우팅 설계
from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
# ViewSetMixin, as_view
url(r'^publish/$', views.PublishView.as_view({'get': 'list', 'post': 'create'})),
url(r'^publish/(?P\d+)', views.PublishView.as_view({'get': 'retrieve', 'put': 'update','delete':'destroy'})),
]
4-2 뷰 함수
from rest_framework.viewsets import ModelViewSet
# ModelViewSet(mixins.CreateModelMixin, mixins.RetrieveModelMixin, mixins.UpdateModelMixin,
# mixins.DestroyModelMixin,
# mixins.ListModelMixin,
# GenericViewSet):
class PublishView(ModelViewSet):
queryset = models.Publish.objects.all()
serializer_class = MySerializer.PublishSerializers
4-3 원본 코드 분석
class ModelViewSet(mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
mixins.ListModelMixin,
GenericViewSet):
"""
A viewset that provides default `create()`, `retrieve()`, `update()`,
`partial_update()`, `destroy()` and `list()` actions.
"""
pass
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Django 라우팅 계층 URLconf 작용 및 원리 해석URL 구성(URLconf)은 Django가 지원하는 웹 사이트의 디렉토리와 같습니다.그것의 본질은 URL과 이 URL을 호출할 보기 함수 사이의 맵표입니다. 위의 예제에서는 URL의 값을 캡처하고 위치 매개 변수로...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.