zoukankan      html  css  js  c++  java
  • DjangoRESTFrameWork中的视图

    DRF中的request

    在Django REST Framework中内置的Request类扩展了Django中的Request类,实现了很多方便的功能--如请求数据解析和认证等。

    比如,区别于Django中的request从request.GET中获取URL参数,从request.POST中取某些情况下的POST数据。

    在APIView中封装的request,就实现了请求数据的解析:

    对于GET请求的参数我们通过request.query_params来获取。

    对于POST请求、PUT请求的数据我们通过request.data来获取。

    视图的使用:

    1 前提之序列化

    # 首先需要在setting中注册rest_framework的中间件
    
    from rest_framework import serializers
    from crm import models
    
    
    class PublisherModel(serializers.ModelSerializer):
        class Meta:
            model =models.Publisher
            fields = '__all__'
    
    
    class AuthorModel(serializers.ModelSerializer):
        class Meta:
            model = models.Author
            fields = '__all__'
    
    
    class BookSerializers(serializers.Serializer):
        id = serializers.IntegerField(required=False)
        name = serializers.CharField(max_length=32)
        pub_date = serializers.DateField()
    
        CHOICES = ((1, 'python'), (2, 'go语言'), (3, 'linux'))
        # source设置数据读取时候读取到 CHOICES里面的内容,read_only设置只在读取时有效
        category = serializers.CharField(source='get_category_display',read_only=True)
        post_category = serializers.IntegerField(write_only=True)
    
        # 对出版社字段进行校验 读取时,和设置是显示的格式不同
        publisher = PublisherSerializers(read_only=True)
        post_publisher = serializers.IntegerField(write_only=True)
    
        # 对作者字段进行校验
        author = AuthorSerializers(many=True, read_only=True)
        post_author = serializers.ListField(write_only=True)
    
    # create方法相当于对每个通过校验的字段进行获取在数据库中新建保存
        def create(self, validated_data):  # validated_data里面保存的是校验通过后的数据
            book_obj = models.Book.objects.create(
                name=validated_data["name"],
                pub_date=validated_data["pub_date"],
                category=validated_data["post_category"],
                publisher_id=validated_data["post_publisher"]
            )
            book_obj.author.set(validated_data["post_author"])  # 多对多字段需要重新设置关系
            return book_obj
    
        def update(self, instance, validated_data):
            # 从validated_data中取出数据挨个字段更新
            instance.name = validated_data.get('name', instance.name)
            instance.pub_date = validated_data.get('pub_date', instance.pub_date)
            instance.category = validated_data.get('post_category', instance.category)
            instance.publisher_id = validated_data.get('post_publisher', instance.publisher_id)
            instance.save()
            # 更新多对多字段的 authors
            # 先取出当前书籍的所有作者id
            author_list = instance.author.all().values_list('id')  # [(1,),(2,)] ==> [1, 2]
    
            instance.author.set(validated_data.get('post_authors', [i[0] for i in author_list]))
            return instance
    serializers

    2 初级阶段

    from rest_framework.response import Response
    from rest_framework.views import APIView
    
    # 图书的展示以及添加
    class Book(APIView):  # 继承改为restframework的封装的APIView
        def get(self, request):
            # 1,在后端获取数据
            book_obj = models.Book.objects.all()
            # 2,使用seriallizers进行数据格式化
            ser_obj = BookSerializers(book_obj, many=True)
            # 返回给前端  Response方法是serializers封装的方法
            return Response(ser_obj.data)
    
        def post(self, request):
            # 1, 在前端获取提交的数据
            # 此时的request已经是被serializers封装过的request,不是简单的页面提交的那个request
            # 前端提交的数据存在request.data里面 print(request.data)
            # 2, 进行serializers校验
            ser_obj = BookSerializers(data=request.data)
            if ser_obj.is_valid():  # 如果通过了校验
                print("oye")
                # 数据校验通过以后,想要使用save方法保存的话,需要调用BookSerializers里面的create方法
                ser_obj.save()
                return Response('数据添加成功!')
            else:  # 没通过校验的数据,返回错误信息
                print('ono')
                return Response(ser_obj.errors)
    
    # 具体图书信息的展示以及修改和删除
    class BookDetail(APIView):  
    
        def get(self, request, pk):
            book_obj = models.Book.objects.filter(pk=pk).first()
           
            if book_obj:
                ser_obj = BookModel(book_obj)  # 对数据进行有效性校验
                return Response(ser_obj.data)  
            else:
                return Response('无效的id')
    
        def put(self, request, pk):
            book_obj = models.Book.objects.filter(pk=pk).first()
            if book_obj:
                ser_obj = BookSerializers(instance=book_obj, data=request.data, partial=True)  # 此处得到request已经是封装过的,partial表示局部更新
                if ser_obj.is_valid():
                    ser_obj.save()
                    return Response(ser_obj.data)
                else:
                    return Response(ser_obj.errors)
            else:
                return Response('无效的id')
        
        def delete(self,request,pk):
            book_obj = models.Book.objects.filter(pk=pk).first()
            if book_obj:
                book_obj.delete()
                return Response("删除成功")
            else:
                return Response("无效的id")

    3 强化版

    from django.contrib import admin
    from django.urls import path,re_path
    from crm import views
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('book/', views.Book.as_view()),
        re_path('book/(?P<pk>d+)/$', views.BookDetail.as_view()),
    
        path('author/', views.Authorshow.as_view()),
        re_path('author/(?P<pk>d+)/$', views.AuthorDetail.as_view()),
    
    
        path('publisher/', views.Publishershow.as_view()),
        re_path('publisher/(?P<pk>d+)', views.PublisherDetail.as_view()),
    
    
    ]
    路由
    # 公共类,获取数据使用
    class GerneridView(APIView):
        queryset = None
        serializer_class = None
    
        def get_queryset(self):
            queryset = self.queryset.all()  # 刷新数据
            return queryset
    
        def get_object(self, request, pk, *args, **kwargs):
            queryset = self.queryset.filter(pk=pk).first()
            return queryset
    
    
    class ListMixin(object):
        def get(self, request):
            queryset = self.get_queryset()
            ser_obj = self.serializer_class(queryset, many=True)
            return Response(ser_obj.data)
    
    
    class CreateMixin(object):
        def post(self, request):
            ser_obj = self.serializer_class(data=request.data)
            if ser_obj.is_valid():
                ser_obj.save()
                return Response('OK')
            else:
                return Response(ser_obj.errors)
    
    
    class ActreveMixin(object):
        def get(self, request, pk, *args, **kwargs):
            obj = self.get_object(request, pk, *args, **kwargs)
            if obj:
                ser_obj = self.serializer_class(obj)
                return Response(ser_obj.data)
            else:
                return Response("无效的id")
    
    
    class UpdateMixin(object):
        def put(self, request, pk, *args, **kwargs):
            book_obj = self.get_object(request, pk, *args, **kwargs)
            if book_obj:
                ser_obj = AuthorModel(instance=book_obj, data=request.data, partial=True)
                if ser_obj.is_valid():
                    ser_obj.save()
                    return Response("数据更新成功")
                else:
                    return Response(ser_obj.errors)
            else:
                return Response("无效的id")
    
    
    class DelMixin(object):
        def delete(self,request, pk, *args, **kwargs):
            obj = self.get_object(request, pk, *args, **kwargs)
            if obj:
                obj.delete()
                return Response('删除成功')
            else:
                return Response("无效的id")
    
    
    class Authorshow(GerneridView, ListMixin, CreateMixin):
        queryset = models.Author.objects.all()
        serializer_class = AuthorModel
    
    
    class AuthorDetail(GerneridView, ActreveMixin, UpdateMixin, DelMixin):
        queryset =models.Author.objects.all()
        serializer_class = AuthorModel
    面向对象封装版

    4 究极进化版

    from django.urls import path,re_path
    from bms import views
    urlpatterns = [
        path('admin/', admin.site.urls),
    
        # 作者相关操作
        path('author/', views.AuthorShow.as_view(actions={'get': 'list', 'post': 'create'})),
        re_path('author/(?P<pk>d+)/$', views.AuthorShow.as_view(actions={'get': 'retrieve', 'put': 'update', 'delete': 'destroy'})),
    
        # 出版社相关操作
        path('publisher/', views.PublisherShow.as_view(actions={'get': 'list', 'post': 'create'})),
        re_path('publisher/(?P<pk>d+)/$', views.PublisherShow.as_view(actions={'get': 'retrieve', 'put': 'update', 'delete': 'destroy'})),
    
        # 图书相关增删改查操作
        path('books/', views.BooksShow.as_view(actions={'get': 'list', 'post': 'create'})),
        re_path('books/(?P<pk>d+)/$', views.BooksShow.as_view(actions={'get': 'retrieve', 'put': 'update', 'delete': 'destroy'})),
    
    ]
    路由
    from bms import models
    # Create your views here.
    from rest_framework.viewsets import ModelViewSet
    from bms.serializer import AuthorModel, PublisherModel, BookModel
    
    
    class AuthorShow(ModelViewSet):
        queryset = models.Author.objects.all()
        serializer_class = AuthorModel
    
    
    class PublisherShow(ModelViewSet):
        queryset = models.Publisher.objects.all()
        serializer_class = PublisherModel
    
    
    class BooksShow(ModelViewSet):
        queryset = models.Book.objects.all()
        serializers = BookModel
    究极进化版

    5 无比强大的路由

    from rest_framework.routers import DefaultRouter
    
    router = DefaultRouter()
    router.register(r'school', views.SchoolView)
    urlpatterns += router.urls

    6 一张不明觉厉的图

  • 相关阅读:
    杭电2081
    杭电2083
    杭电2084
    3/5/2014 cfb 小心
    116
    uva10003
    10815
    127
    674
    uva 13598
  • 原文地址:https://www.cnblogs.com/lingcai/p/10269803.html
Copyright © 2011-2022 走看看