• Django 之restframework1


    Restframework

    这里先简单的介绍一下restful协议

      ----一切皆是资源,操作只是请求方式


    基于restful协议的框架有很多
    Django下的restframework只是其中的一种

    restful协议是一套开发的规范,url里不能有动作相关的词汇,比如add,edit,这些都通过用请求的方式来实现

    以前----book表增删改查
            /books/                    books
            /books/add/                addbook
            /books/(d+)/change/    change
            /books/(d+)/delete        delete
            
            
        现在----book表增删改查
            /books/        ---get        books --->返回所有的数据
            /books//        ---post        books    --->返回提交的数据
            
            /books/(d+)/     ----put        bookdetail    --->返回更新的数据    
            /books/(d+)/    ----delete    bookdetail  ---->返回空
            有参数不一样的class类
            
            class Books(View):
                def get(self,requset):
                    pass #查看所有书籍
                    
                def post(self,request):
                    pass #添加书籍
                    
            class BooksDetail(View):
                def get(self,request,id):
                    pass #查看某一本书籍
            
                def put(self,requset,id):
                    pass #更新书籍
                    
                def delete(self,request,id):
                    pass #删除书籍

    在父类的基础上扩展,并执行父类方法

    继承后调用父类的方法:
        扩展后子类继续调用父类的方法:
        class LoginView(View):
            def dispatch(self,request,*arg,**kwargs):
            # 两种方式都可以
                           print('扩展父类方法')
                ret = super(LoginView,self).dispatch(self,request,*arg,**kwargs)
                ret = super().dispatch(self,request,*arg,**kwargs)
                return ret

    序列化

    创建一个序列化类

    开发我们的Web API的第一件事是为我们的Web API提供一种将代码片段实例序列化和反序列化为诸如json之类的表示形式的方式。

    model类

    rom django.db import models
    
    # Create your models here.
    
    
    class Book(models.Model):
        title=models.CharField(max_length=32)
        price=models.IntegerField()
        pub_date=models.DateField()
        publish=models.ForeignKey("Publish")
        authors=models.ManyToManyField("Author")
        def __str__(self):
            return self.title
    
    class Publish(models.Model):
        name=models.CharField(max_length=32)
        email=models.EmailField()
        def __str__(self):
            return self.name
    
    class Author(models.Model):
        name=models.CharField(max_length=32)
        age=models.IntegerField()
        def __str__(self):
            return self.name
    model

    views部分:

    from rest_framework.views import APIView
    from rest_framework.response import Response
    from .models import *
    from django.shortcuts import HttpResponse
    from django.core import serializers
    
    
    from rest_framework import serializers
    
    class BookSerializers(serializers.Serializer):
        title=serializers.CharField(max_length=32)
        price=serializers.IntegerField()
        pub_date=serializers.DateField()
        # 一对多核多对多需要我们自己构建
        publish=serializers.CharField(source="publish.name")
        #authors=serializers.CharField(source="authors.all")
        authors=serializers.SerializerMethodField()
        def get_authors(self,obj):
            temp=[]
            for author in obj.authors.all():
                temp.append(author.name)
            return temp
    
    
    class BookViewSet(APIView):
    
        def get(self,request,*args,**kwargs):
            book_list=Book.objects.all()
            # 序列化方式1:
            # from django.forms.models import model_to_dict
            # import json
            # data=[]
            # for obj in book_list:
            #     data.append(model_to_dict(obj))
            # print(data)
            # return HttpResponse("ok")
    
            # 序列化方式2:
            # data=serializers.serialize("json",book_list)
            # return HttpResponse(data)
    
            # 序列化方式3:
            bs=BookSerializers(book_list,many=True)
            return Response(bs.data)
    View Code

     

    上面能做的知识单纯的将queryset序列化,那么有没有能够既能够序列化对象传给前端,

    又能够接受前端的数据然后更新到数据库呢?

    ModelSerializer

    modelserializer和modelform很类似,用法也很相似.

    class BookSerializers(serializers.ModelSerializer):
          class Meta:
              model=Book
              fields="__all__"
              depth=1

    提交post请求

     def post(self,request,*args,**kwargs):
           
            bs=BookSerializers(data=request.data,many=False)
            if bs.is_valid():
                # print(bs.validated_data)
                bs.save()
                return Response(bs.data)
            else:
                return Response(bs.errors)

    重写save和create方法

    class BookSerializers(serializers.ModelSerializer):
    
          class Meta:
              model=Book
              fields="__all__"
              # exclude = ['authors',]
              # depth=1
    
          def create(self, validated_data):
            
              authors = validated_data.pop('authors')
              obj = Book.objects.create(**validated_data)
              obj.authors.add(*authors)
              return obj

     单条数据的get和put请求

    class BookDetailViewSet(APIView):
    
        def get(self,request,pk):
            book_obj=Book.objects.filter(pk=pk).first()
            bs=BookSerializers(book_obj)
            return Response(bs.data)
    
        def put(self,request,pk):
            book_obj=Book.objects.filter(pk=pk).first()
            bs=BookSerializers(book_obj,data=request.data)
            if bs.is_valid():
                bs.save()
                return Response(bs.data)
            else:
                return Response(bs.errors)

    我们可以看到中间CBV的类继承了restframework的APIView,那么里面的继承关系,和流程是怎么样的呢?

    url(r'^books/$', views.BookView.as_view(),name="books")# View下的view

    books/一旦被访问: view(request) ------APIView: dispatch()

    在restframework的dispatch方法里干了什么事?

    重新构建request对象
    self.request=Request(request)
    self.request._request

    分发----if get请求:
    if request.method.lower() in self.http_method_names:
    handler = getattr(self, request.method.lower(),
    self.http_method_not_allowed)
    else:
    handler = self.http_method_not_allowed
    
    response = handler(request, *args, **kwargs) # self.get(request, *args, **kwargs)
    
    return response

    流程图:

     

    Django原生的request:

    如何在重构的request对象里获取数据?

    request.GET  # get
    
    request.data # POST  PUT delete

    超链接API:Hyperlinked

    class BookSerializers(serializers.ModelSerializer):
          publish= serializers.HyperlinkedIdentityField(
                         view_name='publish_detail',
                         lookup_field="publish_id",
                         lookup_url_kwarg="pk")
          class Meta:
              model=Book
              fields="__all__"
              #depth=1

    urls部分:

    urlpatterns = [
        url(r'^books/$', views.BookViewSet.as_view(),name="book_list"),
        url(r'^books/(?P<pk>d+)$', views.BookDetailViewSet.as_view(),name="book_detail"),
        url(r'^publishers/$', views.PublishViewSet.as_view(),name="publish_list"),
        url(r'^publishers/(?P<pk>d+)$', views.PublishDetailViewSet.as_view(),name="publish_detail"),
    ]

     

    参考这里

  • 相关阅读:
    Android调用系统相机和相册并解决data为空,OOM,图片角度不对的问题
    Android 工作流提交审批填写审批意见PopWindow工具类
    解决ionic安装不上的方法
    nodeJs 报maximum call stack size exceeded js
    命令行运行ionic run android 出现running one or more of the platforms Error
    Ionic run android失败解决方法。
    Android Scrollview嵌套下listView动态加载数据,解决onScrollChanged执行多次数据重复问题
    Android 自定义ListView动态加载数据
    Android ListView显示不同样式的item
    day 43
  • 原文地址:https://www.cnblogs.com/chenxuming/p/9338210.html
Copyright © 2020-2023  润新知