zoukankan      html  css  js  c++  java
  • rest-framework之视图

    1、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来获取。


    from rest_framework import viewsets这个viewset中,有5类Minxin,他们与http方法对应如下:

    image


    2、基本视图之初学乍练

    写一个出版社的增删查改resful接口:

    urls.py

    url(r'^publish/$', views.PublishView.as_view()),
    url(r'^publish/(?P<pk>d+)/$', views.PublishDetailView.as_view()),


    views.py,因为获取(get)一个和获取(get)多个会有冲突,所以要写两个接口类

    class PublishSerializers(serializers.ModelSerializer):
        class Meta:
            model=models.Publish
            fields='__all__'
    
    class PublishView(APIView):
    
        def get(self, request):
            publish_list = models.Publish.objects.all()
            bs = PublishSerializers(publish_list, many=True)
            # 序列化数据
    
            return Response(bs.data)
    
        def post(self, request):
            # 添加一条数据
            print(request.data)
    
            bs=PublishSerializers(data=request.data)
            if bs.is_valid():
                bs.save()  # 生成记录
                return Response(bs.data)
            else:
    
                return Response(bs.errors)
    
    class PublishDetailView(APIView):
        def get(self,request,pk):
            publish_obj=models.Publish.objects.filter(pk=pk).first()
            bs=PublishSerializers(publish_obj,many=False)
            return Response(bs.data)
        def put(self,request,pk):
            publish_obj = models.Publish.objects.filter(pk=pk).first()
    
            bs=PublishSerializers(data=request.data,instance=publish_obj)
            if bs.is_valid():
                bs.save() # update
                return Response(bs.data)
            else:
                return Response(bs.errors)
        def delete(self,request,pk):
            models.Publish.objects.filter(pk=pk).delete()
    
            return Response("")


    models.py参考下面的;


    3、mixin类和generice类编写视图之上层武功

    settings.py

    INSTALLED_APPS = [
        ...
        'rest_framework',
    ]


    models.py

    from django.db import models
    
    # Create your models here.
    class Book(models.Model):
        nid = models.AutoField(primary_key=True)
        name = models.CharField(max_length=32)
        price = models.DecimalField(max_digits=5, decimal_places=2)
        publish_date = models.DateField(null=True)
        xx=models.IntegerField(choices=((0,'文学类'),(1,'情感类')),default=1,null=True)
        publish = models.ForeignKey(to='Publish',to_field='nid',on_delete=models.CASCADE,null=True)
        authors=models.ManyToManyField(to='Author')
        def __str__(self):
            return self.name
        def test(self):
            return 'xxx'
    
    
    class Author(models.Model):
        nid = models.AutoField(primary_key=True)
        name = models.CharField(max_length=32)
        age = models.IntegerField()
    
    
    
    class Publish(models.Model):
        nid = models.AutoField(primary_key=True)
        name = models.CharField(max_length=32)
        city = models.CharField(max_length=32)
        email = models.EmailField()
    
        def __str__(self):
            return self.name


    执行数据库迁移命令;

    插入数据:

    image


    views.py

    from django.shortcuts import render
    from rest_framework.views import APIView
    from rest_framework import serializers
    from app01 import models
    from rest_framework.response import Response
    
    # Create your views here.
    
    # 基于mixins来封装的视图
    from rest_framework.mixins import CreateModelMixin,RetrieveModelMixin,ListModelMixin,UpdateModelMixin,DestroyModelMixin
    from rest_framework.generics import GenericAPIView
    
    class PublishView(CreateModelMixin, ListModelMixin, GenericAPIView):
        queryset = models.Publish.objects.all()
        serializer_class = PublishSerializers
        def post(self, request, *args, **kwargs):
            return self.create(request, *args, **kwargs)
    
        def get(self, request, *args, **kwargs):
            return self.list(request, *args, **kwargs)
    
    
    class PublishDetailView(RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin, GenericAPIView):
        queryset = models.Publish.objects.all()
        serializer_class = PublishSerializers
        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 delete(self, request, *args, **kwargs):
            return self.destroy(request, *args, **kwargs)


    urls.py

    from django.conf.urls import url
    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<pk>d+)/$', views.PublishDetailView.as_view()),
    ]


    用postman测试:

    post创建:

    image


    get获取:

    image


    put更新:

    image


    delete删除:

    image


    4、使用generics 下ListCreateAPIView, RetrieveUpdateDestroyAPIView之高深武功

    models.py  urls.py和上面都一样;


    views.py

    from django.shortcuts import render
    from rest_framework.views import APIView
    from rest_framework import serializers
    from app01 import models
    from rest_framework.response import Response
    from rest_framework import viewsets
    
    
    class PublishSerializers(serializers.ModelSerializer):
        class Meta:
            model=models.Publish
            fields='__all__'
    
    
    
    # 第三种写法
    from rest_framework.generics import CreateAPIView, ListCreateAPIView, RetrieveUpdateDestroyAPIView
    
    class PublishView(ListCreateAPIView):
        queryset=models.Publish.objects.all()
        serializer_class = PublishSerializers
    
    
    class PublishDetailView(RetrieveUpdateDestroyAPIView):
        queryset=models.Publish.objects.all()
        serializer_class = PublishSerializers


    5、使用ModelViewSet 之终极大法

    urls.py

    from django.conf.urls import url
    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<pk>d+)/$', views.PublishDetailView.as_view()),
        url(r'^publish/$', views.PublishView.as_view({'get': 'list', 'post': 'create'})),
        url(r'^publish/(?P<pk>d+)/$',views.PublishView.as_view({'get': 'retrieve', 'put': 'update', 'delete': 'destroy'})),
    ]


    views.py

    from rest_framework.viewsets import ModelViewSet
    class PublishView(ModelViewSet):
        queryset=models.Publish.objects.all()
        serializer_class=PublishSerializers


    6、扩展

    a、如果有的功能不能满足开发需求时,可以重新一些方法;


    b、继承ViewSetMixin 改写路由与视图

    views.py

    from rest_framework.viewsets import ViewSetMixin
    from rest_framework.views import APIView
    
    # ViewSetMixin重写了as_view方法
    # 我们可以写一个类继承ViewSetMixin,和APIView,要保证这种继承顺序
    # 写一个aaa方法,(可以写多个不同的方法)
    class Test(ViewSetMixin, APIView):
        def aaa(self, request):
            return Response()
        def bbb(self, request):
            return Response()


    urls.py

    # 此时路由中就可以这样写了,当有get请求时就会走我们在views.py中定义的aaa方法
    url(r'^aa/$', views.PublishView.as_view({'get': 'aaa', })),

    # 访问bb路径时,get请求时就会走我们在views.py中定义的bbb方法
    
    url(r'^bb/$', views.PublishView.as_view({'get': 'bbb', })),


    7、视图组件总结

    1)DRF所有视图文件

    所有的视图类在如下这四个文件内:

    from rest_framework import views       # APIView
    from rest_framework import generics    # 公共通用视图类:GenericAPIView,及各种组合视图类CreateAPIView、ListAPIView、RetrieveAPIView等
    from rest_framework import mixins      # 混合继承类:CreateModelMixin、ListModelMixin、RetrieveModelMixin、UpdateModelMixin、DestroyModelMixin
    from rest_framework import viewsets    # 重写as_view: ViewSetMixin;其他类都是帮助去继承ViewSetMixin


    2)DRF视图图谱

    视图类继承顺序,如下图所示:

    说明:

    1、首先 django是继承 view的,DRF是从APIView开始继承起,APIView封装了request,其中包含了data、query_params等属性、方法。
    
    2、然后 GenericAPIView封装了 get_queryset() 和 get_serializer();ViewSetMixin重写了 as_view()方法。
    
    3、随后 GenericViewSet继承GenericAPIView和ViewSetMixin。
    
    4、最后最高层的封装是 ModelViewSet。
  • 相关阅读:
    kali渗透综合靶机(八)--Billu_b0x靶机
    kali渗透综合靶机(七)--Super-Mario-Host靶机
    kali渗透综合靶机(九)--Typhoon靶机
    【Flask】 python学习第一章
    【HICP Gaussdb】数据库 数据库管理(连接方式 会话模式 存储表空间)-6
    【HICP Gaussdb】数据库 数据库管理(shutdown 日志 连接命令)-5
    【HCIA Gaussdb】学习汇总-数据库管理(数据库基本概念)-3
    【Flask】 python学习第一章
    【HCIA Gaussdb】学习汇总-数据库管理-2
    【HICP Gaussdb】数据库 数据库管理(调优 启动流程)-4
  • 原文地址:https://www.cnblogs.com/weiyiming007/p/12517650.html
Copyright © 2011-2022 走看看