drf - 보기 가족

원본 링크:http://www.cnblogs.com/Hades123/p/11488667.html
목차
  • drf 보기 가족
  • 초기 준비
  • 총 경로 urls. py
  • 기본 표: utils / models. py
  • 모델 층 api / models. py
  • 직렬 화기 api / serializers. py
  • 기본 보기 (views)
  • 하위 경로 api / urls. py
  • 보기 층 api / views. py
  • 보기 도구 류 (mixins)
  • 도구 보기 (generics)
  • GenericAPIView
  • GenericAPIView 의 하위 클래스 들
  • 하위 경로 api / urls. py
  • 보기 층 api / views. py
  • 이미지 세트 (viewsets)
  • 하위 경로 api / urls. py
  • 보기 층 api / views. py


  • drf 보기 가족
    전기 준비
    총 경로 urls. py
    from django.contib import admin
    from django.views import serve
    from django.conf import settings
    
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^api/', include('api.urls')),
        url(r'^media/(?P.*)', serve, {'document_root': settings.MEDIA_ROOT}),
    ]

    기본 표: utils / models. py
    from django.db import models
    
    class BaseModel(models.Model):
        is_delete = models.BooleanField(default=False)
        create_time = models.DateTimeField(auto_now_add=True, null=True)
        
        class Meta:
            #    ,          
            abstract = True

    모형 층 api / models. py
    from django.db import models
    from utils.models import BaseModel
    
    class Book(BaseModel):
        name = models.CharField(max_length=64)
        price = models.DecimalField(max_digits=6, decimal_places=2)
        img = models.ImageField(upload_to='icon', default='icon/default.png')
        publish = models.ForeignKey(to='Publish',
                                    null=True,
                                    related_name='books',
                                    db_constraint=False,
                                    on_delete=models.DO_NOTHING
                                    )
        authors = models.ManyToManyField(to='Author',
                                         related_name='authors',
                                         db_constraint=False
    
        @property
        def publish_info(self):
            return {'name': self.publish.name, 'address': self.publish.address}
        
        @property
        def author_info(self):
            author_list = []
            
            for author in self.authors.all():
                detail = AuthorDetail.objects.filter(author_id=self.author.id)
                author_list.append({
                    'name': author.name,
                    'age': author.age,
                    'mobile': '  ' if not detail else author.detail.mobile
                })
                
            return author_list
            
    
        class Meta:
            db_table = "books"
            verbose_name = '  '
            verbose_name_plural = verbose_name
    
        def __str__(self):
            return self.name
    
    
    class Author(BaseModel):
        name = models.CharField(max_length=64)
        age = models.IntegerField()
    
        @property
        def mobile(self):
            return self.detail.mobile
        
        class Meta:
            db_table = 'author'
            verbose_name = '  '
            verbose_name_plural = verbose_name
    
        def __str__(self):
            return self.name
    
    
    class AuthorDetail(BaseModel):
        mobile = models.CharField(max_length=11)
        author = models.OneToOneField(to='Author',
                                      null=True,
                                      related_name='detail',
                                      db_constraint=False,
                                      on_delete=models.CASCADE
                                      )
        class Meta:
            db_table = 'detail'
            verbose_name = '    '
            verbose_name_plural = verbose_name
    
        def __str__(self):
            return f"{self.author.name}   "
    
    
    class Publish(BaseModel):
        name = models.CharField(max_length=64)
        address = models.CharField(max_length=128)
    
        class Meta:
            db_table = 'publish'
            verbose_name = '   '
            verbose_name_plural = verbose_name
    
        def __str__(self):
            return self.name

    직렬 화 기 api / serializers. py
    from rest_framework import serializers
    from . import models
    
    class BookListSerializer(serializers.ListSerializer):
        def update(self, instance, validated_data):
            for ind, obj in enumerate(instance):
                for attr, value in validated_data[ind].items():
                    if hasattr(obj, attr):
                        set(obj, attr, value)   
                obj.save()
            return instance
    
    class BookV2ModelSerializer(serializers.ModelSerializer):
        re_name = serializers.CharField(
            min_length=3, 
            required=True, 
            write_only=True,  #        
            error_messages={
                'min_length': '   ',
                'required': '    '
            }
        )
        
        class Meta:
            model = models.Book
            fields = ('name', 're_name', 'price', 'img', 'publish', 'publish_info', 'authors', 'authors_info')
            list_serializer_class = BookListSerializer
             extra_kwargs = {
                'name':{
                    'min_length': 3,
                    'error_messages': {
                        'min_length': '   ',
                        'required': '    '
                    }
                },
                #           required False,                 ,            
                'publish':{
                    'required': True,
                    'write_only': True,
                    'error_messages':{
                        'required': '    '
                    }
                },
                'authors':{
                    'required': True,
                    'write_only': True,
                    'error_messages':{
                        'required': '    '
                    }
                },
            }
                
            #        
            #     
            def validate_name(self, value):
                if 'sb' in value:
                    raise serializers.ValidationError('        ')
                return value
            
            #     
            def validate(self, attr):
                name = attr.get('name')
                re_name = attr.get('re_name')
                publish = attr.get('publish')
                if name != re_name:
                    raise serializers.ValidationError(
                        {'re_name': '       '}
                    )
                    
                #           
                if models.Book.objects.filter(name=name, publish=publish):
                    raise serializers.ValidationError(
                        {'book': '     '}
                    )   
                return attr  

    기본 보기 (views)
    주로 보기 류 APIView 를 통 해 안의 논 리 는 모두 스스로 실현 해 야 하고 스스로 인 터 페 이 스 를 써 야 한다.
    하위 경로 api / urls. py
    from django.conf.urls import url
    from . import views
    urlpatterns = [
        url(r'^books/$', views.BookAPIView.as_view()),
        url(r'^books/(?P.*)/$', views.BookAPIView.as_view()),
    ]

    보기 층 api / views. py
    from rest_framework import views
    from . import models, serializers
    from utils.response import APIResponse
    
    class BookAPIView(views.APIView):
        def get(self, request, *args, **kwargs):
            pk = kwargs.get('pk')
            #   
            if pk:
                book_obj = models.Book.objects.filter(is_delete=False, pk=pk).first()
                if not pk:
                    return APIResponse(1, 'pk  ')
                book_ser = serializers.BookV2ModelSerializer(book_obj)
                return APIResponse(0, 'ok', results=book_ser.data)
    
            #   
            book_obj_list = models.Book.objects.filter(is_delete=False).all()
            if not book_obj_list:
                return APIResponse(1, '    ')
            book_ser = serializers.BookV2ModelSerializer(book_obj_list, many=True)
            return APIResponse(0, 'ok', results=book_ser.data)
    
        #   
       def post(self, request, *args, **kwargs):
            #          
            request_data = request.data
            if isinstance(request_data, dict):
                data = [request_data, ]
            elif isinstance(request, list):
                data = request_data
            else:
                return APIView(1, '      ')
            
            book_ser = serializers.BookV2ModelSerializer(data=data, many=True)
            if book_ser.is_valid():
                book_obj_list = book_ser.save()
                results = serializers.BookV2ModelSerializer(book_obj_list, many=True).data
                return APIResponse(0, 'ok', results=results)
            else:
                return APIResponse(1, '    ', results=book_ser.errors)

    보기 도구 클래스 (mixins)
  • RetrieveModelMixin: retrieve 방법 으로 대상 획득
  • ListModelMixin: list 방법 으로 여러 대상 획득
  • CreateModelMixin: create 방법 은 하나의 대상 을 추가 하 는 것 을 실현 했다
  • UpdateModelMixin: update 방법 은 단일 업데이트, parialudate 는 단일 부분 업데이트
  • 를 실현 했다.
  • DestroyModelMixin: destory 방법 으로 단독 삭제
  • 일반 generics 도구 보기 와 결합 하여 사용 합 니 다.
    도구 보기 (generics)GenericAPIView GenericAPIView 는 generics 가족의 기본 유형 으로 주로 qureysetserializer_class 을 속성 으로 포장 하여 다음 과 같은 세 가지 방법 을 제공 합 니 다.
  • get_qureyset(): 여러 대상 얻 기
  • get_object():
  • get_serializer(*args, **kwargs): 서열 화 된 대상 획득
  • GenericAPIView 의 부류 들mixins 중의 여러 기능 류 와 GenericAPIView 기 류 를 계승 했다.
    유명무실 하 다
    실현 인터페이스CreateAPIView
    단일 증가 (post)ListAPIView
    많이 가 져 오기 (get)RetrieveAPIView
    체크 (get)DestroyAPIView
    삭제UpdateAPIView
    단일 부분 (patch) 및 전체 (put) 수정ListCreateAPIView
    다 중 추출 (get) 과 다 중 추가 (post)RetrieveUpdateAPIView
    단일 추출 (get), 단일 부분 (patch) 및 전체 (put) 수정RetrieveDestroyAPIView
    단일 추출 (get) 과 단일 삭제 (delete)RetrieveUpdateDestroyAPIView
    단일 추출 (get), 단일 부분 (patch) 및 전체 (put) 수정 및 삭제 (delete)
    하위 경로 api / urls. py
    from django.conf.urls import url
    from . import views
    urlpatterns = [
        # generics
        url(r'^v1/books/$', views.BookGenericAPIView.as_view()),
        url(r'^v1/books/(?P.*)/$', views.BookGenericAPIView.as_view()),
        
        # mixins + generics
        url(r'^v2/books/$', views.BookMixinsGenericAPIView.as_view()),
        url(r'^v2/books/(?P.*)/$', views.BookMixinsGenericAPIView.as_view()),
        
        #     mixins、generics
        url(r'^v3/books/$', views.BookRetrieveUpdateAPIView.as_view()),
        url(r'^v3/books/(?P.*)/$', views.BookRetrieveUpdateAPIView.as_view()),
    ]

    보기 층 api / views. py
    from rest_framework import generics, mixins
    from . import models, serializers
    from utils.response import APIResponse
    
    # v1 generics -     
    class BookGenericAPIView(generics.GenericAPIView):
        queryset = models.Book.objects.filter(is_delete=False).order_by('-id')
        serializer_class = serializers.BookModelSerializer
    
        def get(self, request, *args, **kwargs):
            if 'pk' in kwargs:
                book_obj = self.get_object()
                book_ser = self.get_serializer(book_obj)
                return APIResponse(0, 'ok', results=book_ser.data)
            book_query = self.get_queryset()
            book_ser = self.get_serializer(book_query, many=True)
            return APIResponse(0, 'ok', results=book_ser.data)
    
        def post(self, request, *args, **kwargs):
            book_ser = self.get_serializer(data=request.data)
            book_ser.is_valid(raise_exception=True)
            book_obj = book_ser.save()
            return APIResponse(0, 'ok', results=self.get_serializer(book_obj).data)
    
    # v2 mixins    + generics    
    class BookMixinsGenericAPIView(mixins.RetrieveModelMixin, mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView):
        queryset = models.Book.objects.filter(is_delete=False).order_by('-id')
        serializer_class = serializers.BookModelSerializer
        def get(self, request, *args, **kwargs):
            if 'pk' in kwargs:
                response = self.retrieve(request, *args, **kwargs)
            else:
                response = self.list(request, *args, **kwargs)
            return APIResponse(0, 'ok', results=response.data)
    
        def post(self, request, *args, **kwargs):
            response = self.create(request, *args, **kwargs)
            return APIResponse(0, 'ok', results=response.data)
    
    # v3        -      
    class BookRetrieveUpdateAPIView(generics.RetrieveUpdateAPIView):
        queryset = models.Book.objects.filter(is_delete=False).order_by('-id')
        serializer_class = serializers.BookModelSerializer
    

    그림 모음 (viewset)ViewSetMixin: 그림 집합 도 구 를 보고 as view 방법 을 재 작성 하여 보기 류 에 요청 하 는 방법 에 대한 맵 을 완성 하 였 습 니 다.
    예 를 들 어 .as_view({'get': 'retrieve', 'delete': 'remove_obj'}) 요청 방식 이 get 일 때 retrieve 함 수 를 호출 하고 요청 방식 이 delete 일 때 remove obj 함 수 를 호출 합 니 다.GenericViewSet: 모델 류 와 관련 된 인터페이스 그림 집 - mixins 에서 기능 을 계승 할 수 있 고 사용자 정의 기능 도 가능 합 니 다.ViewSet: 모델 류 와 무관 하거나 표준 모델 류 인터페이스 가 아 닙 니 다. - 보통 사용자 정의 기능 입 니 다.
    하위 경로 api / urls. py
    from django.conf.urls import url
    from . import views
    urlpatterns = [
        url(r'^v4/books/$', views.BookGenericViewSet.as_view({
            'get': 'list',
            'post': 'create'
        })),
        url(r'^v4/books/(?P.*)/$', views.BookGenericViewSet.as_view({
            'get': 'retrieve',
            'put': 'update',
            'patch': 'partial_update',
            'delete': 'remove_book'
        })),
    ]

    보기 층 api / views. py
    from rest_framework import mixins, viewsets
    from . import models, serializers
    from utils.response import APIResponse
    
    class BookGenericViewSet(mixins.RetrieveModelMixin, mixins.ListModelMixin, mixins.CreateModelMixin, mixins.UpdateModelMixin, viewsets.GenericViewSet):
        queryset = models.Book.objects.filter(is_delete=False).order_by('-id')
        serializer_class = serializers.BookModelSerializer
    
        def remove_book(self, request, *args, **kwargs):
            pk = kwargs.get('pk')
            try:
                book_obj = models.Book.objects.get(is_delete=False, pk=pk)
                book_obj.is_delete = True
                book_obj.save()
                return APIResponse(0, '    ')
            except:
                return APIResponse(1, '    ')

    다음으로 전송:https://www.cnblogs.com/Hades123/p/11488667.html

    좋은 웹페이지 즐겨찾기