• rest-framework序列化


    Quickstart

    序列化

    开篇介绍:

         ----  一切皆是资源,操作只是请求方式
         
         ----book表增删改查
             /books/                 books
             /books/add/             addbook
             /books/(d+)/change/    changebook
             /books/(d+)/delete/    delbook
             
        ----book表增删改查
             /books/     -----get            books      -----  返回当前所有数据
             /books/     -----post           books      -----  返回提交数据 
             
             /books/(d+)-----get            bookdetail -----  返回当前查看的单条数据 
             /books/(d+)-----put            bookdetail -----  返回更新数据 
             /books/(d+)-----delete         bookdetail -----  返回空
             
                  
             class  Books(View):
                  def get(self,request):
                      pass  # 查看所有书籍
                      
                  def post(self,request):
                      pass  # 添加书籍
                      
                      
             class  BooksDetail(View):
                  def get(self,request,id):
                      pass  # 查看具体书籍
             
                  def put(self,request,id):
                      pass  # 更新某本书籍
                      
                  def delete(self,request,id):
                      pass  # 删除某本书籍      
             

    创建一个序列化类

    简单使用

    开发我们的Web API的第一件事是为我们的Web API提供一种将代码片段实例序列化和反序列化为诸如json之类的表示形式的方式。我们可以通过声明与Django forms非常相似的序列化器(serializers)来实现。

    models部分:

    from 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",on_delete=models.CASCADE)
        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

    views部分:

    from django.shortcuts import render,HttpResponse
    import json
    from django.views import View
    from .models import *
    from app01.serialize import *
    from rest_framework.views import APIView
    from rest_framework.response import Response
    from rest_framework import serializers   #这是rest_framework的序列化组件

    #为queryset(需要加many=True),model对象做序列化 class PublishSerializers(serializers.Serializer): name =serializers.CharField() email=serializers.CharField() class PublishView(APIView): def get(self,request): #取数据 print(request.GET) publish_list = Publish.objects.all() #序列化 #方式一: #publish_list=list(Publish.objects.all().values("name","email")) #方式二: # from django.forms.models import model_to_dict # publish_list = Publish.objects.all() # temp=[] # for obj in publish_list: # #利用这方法可以将字段和值对应组合成一个字典,一条数据一个字典。 # temp.append(model_to_dict(obj)) #方式三 # from django.core import serializers # publish_list = Publish.objects.all() # ret=serializers.serialize("json",publish_list) #方式四(restframework序列化) ps=PublishSerializers(publish_list,many=True) return HttpResponse(ps.data)

    一对多和多对多字段的序列化:

    class BookSerializers(serializers.Serializer):
        title = serializers.CharField(max_length=32)
        price = serializers.IntegerField()
        pub_date = serializers.DateField()
    
        publish = serializers.CharField(source="publish.email")  # 一对多字段使用source字段处理
    
        # 多对多使用下面字段,并且配一个方法,方法里面可自定义任意东西,可取作者表的名字。
        authors = serializers.SerializerMethodField()
    
        def get_authors(self, obj):
            temp = []
            for obj in obj.authors.all():
                temp.append(obj.name)
            return temp

    序列化的过程:

    '''
    序列化BookSerializers(book_list,many=True)过程:
        temp=[]
        for obj in book_list:
            temp.append({
                "title":obj.title,
                "price":obj.price,
                "pub_date":obj.pub_date,
                #"publish":str(publish),
                "publish":obj.publish.name,
                "authors":get_authors(obj)
    
            })
    '''

    ModelSerializer(类似于ModelForm):

    class PublishModelSerializers(serializers.ModelSerializer):
        class Meta:
            model = Publish
            fields = "__all__"

    提交post请求:

        def post(self,request):
            #原生request支持的操作
            # print(request.POST)
            # print(request.body)
            # print(type(request))
            from django.core.handlers.wsgi import WSGIRequest
    
    
            #新的request支持的操作
            print("request_data",request.data) #request_data {'name': 'jesi', 'email': '666@qq.com'}
            print("request_data_type",type(request.data))   #request_data_type <class 'dict'>
    
            return HttpResponse("POST")

    get和post:

    class BookView(APIView):
        def get(self,request):
            book_list=Book.objects.all()
            # bs=BookSerializers(book_list,many=True)
            bs2=BookModelSerializers(book_list,many=True,context={'request': request})
            # return Response(bs.data)
            return Response(bs2.data)
    
    
        def post(self,request):
            #post请求的数据
            bs=BookModelSerializers(data=request.data)
         #post请求过来的数据如果通过了校验就创建一条数据,如果没有返回错误信息。
    if bs.is_valid(): bs.save() return Response(bs.data) else: return Response(bs.errors)

    重写save中的create方法:

    # ModelSerializers
    class BookModelSerializers(serializers.ModelSerializer):
        class Meta:
            model = Book
            fields = "__all__"
        # publish = serializers.CharField(source="publish.pk")  # 一对多字段使用source字段处理 

      

        # 因为上面自定制了字段,所以这个添加方法需要重写才可以。
        def create(self, validated_data):
            print(validated_data)
            book = Book.objects.create(title=validated_data["title"], price=validated_data["price"],
                                       pub_date=validated_data["pub_date"], publish_id=validated_data["publish"]["pk"])
            book.authors.add(*validated_data["authors"])
            return book

     整体:

    class BookModelSerializers(serializers.ModelSerializer):
        class Meta:
            model = Book
            fields = "__all__"
    
        publish = serializers.CharField(source="publish.pk")  # 一对多字段使用source字段处理
    
        #
        # #多对多使用下面字段,并且配一个方法,方法里面可自定义任意东西,可取作者表的名字。
        # authors=serializers.SerializerMethodField()
        # def get_authors(self,obj):
        #     temp=[]
        #     for obj in obj.authors.all():
        #         temp.append(obj.name)
        #     return temp
    
        # 因为上面自定制了字段,所以这个添加方法需要重写才可以。
        def create(self, validated_data):
            print(validated_data)
            book = Book.objects.create(title=validated_data["title"], price=validated_data["price"],
                                       pub_date=validated_data["pub_date"], publish_id=validated_data["publish"]["pk"])
            book.authors.add(*validated_data["authors"])
            return book

     单条数据的get和put请求:

    直接通过序列化的实例对象做一个校验,对传入的ID值对应的书籍进行增删改查。

    class BookDetailView(APIView):
        def get(self,request,id):
            #单条数据查看
            book=Book.objects.filter(pk=id).first()
            bs=BookModelSerializers(book,context={'request': request})
            return Response(bs.data)
    
        def put(self,request,id):
            #更新单条数据
            book=Book.objects.filter(pk=id).first()
    
            bs = BookModelSerializers(book,request.data)
            if bs.is_valid():
                bs.save()
                return Response(bs.data)
            else:
                return Response(bs.errors)
    
        def delete(self,request,id):
            Book.objects.filter(pk=id).delete()
            return Response()

    超链接API:Hyperlinked

    class BookModelSerializers(serializers.ModelSerializer):
        class Meta:
            model = Book
            fields = "__all__"
        publish=serializers.HyperlinkedIdentityField(
            view_name="publishdetail",
            lookup_field="publish_id",
            lookup_url_kwarg="id",
    
        )

    urls部分:

    urlpatterns = [
        path('admin/', admin.site.urls),
        url(r'publishes/$', views.PublishView.as_view(),name="publish"),
        url(r'publishes/(?P<id>d+)/$', views.PublishDetailView.as_view(),name="publishdetail"),
        url(r'books/$', views.BookView.as_view(),name="books"),
        url(r'books/(d+)/$', views.BookDetailView.as_view(),name="bookdetail"),
    ] 

     这里有一个点需要注意一下:

    class BookView(APIView):
        def get(self,request):
            book_list=Book.objects.all()
            # bs=BookSerializers(book_list,many=True)
            bs2=BookModelSerializers(book_list,many=True,context={'request': request})
            # return Response(bs.data)
            return Response(bs2.data)
    
    
    
    class BookDetailView(APIView):
        def get(self,request,id):
            #单条数据查看
            book=Book.objects.filter(pk=id).first()
            bs=BookModelSerializers(book,context={'request': request})
            return Response(bs.data)

     最后总结:

    总结:
            1 reuqest类----源码
            
            2 restframework 下的APIView--源码
            
              url(r'^books/$', views.BookView.as_view(),name="books")#  View下的view
    
              books/一旦被访问: view(request) ------APIView: dispatch()
            
            3 def dispatch():
            
                  构建request对象
                  self.request=Request(request)
                  self.request._request
                  self.request.GET  # get
                  self.request.data # POST  PUT
              
                  分发----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                
                
            4 序列化类
                # from django.core import serializers
                # ret=serializers.serialize("json",publish_list)
            
                restframework下的序列类  BookModelSerializers
                    将queryset或者model对象序列成一json数据
                        bs=BookModelSerializers(book_list,many=True,context={'request': request})
                        bs=BookModelSerializers(book,context={'request': request})
               
                    还可以做校验数据,json-------》queryset/model-->记录
                    
                        bs=BookModelSerializers(data=request.data)
                        if bs.is_valid():
                            print(bs.validated_data)
                            bs.save() # 重写create方法
            5 操作数据:
            
                以Book表为例
                    class BookView(APIView):
                        # 查看所有书籍
                        def get(self,request):
                            book_list=Book.objects.all()
                            bs=BookModelSerializers(book_list,many=True,context={'request': request})
                            return Response(bs.data)
                            
                        # 添加一本书籍    
                        def post(self,request):
                            # post请求的数据
                            bs=BookModelSerializers(data=request.data)
                            if bs.is_valid():
                                print(bs.validated_data)
                                bs.save()# create方法
                                return Response(bs.data)
                            else:
                                return Response(bs.errors)
    
                    class BookDetailView(APIView):
                        # 查看一本书籍
                        def get(self,request,id):
    
                            book=Book.objects.filter(pk=id).first()
                            bs=BookModelSerializers(book,context={'request': request})
                            return Response(bs.data)
                        # 更新一本书籍
                        def put(self,request,id):
                            book=Book.objects.filter(pk=id).first()
                            bs=BookModelSerializers(book,data=request.data)
                            if bs.is_valid():
                                bs.save()
                                return Response(bs.data)
                            else:
                                return Response(bs.errors)
                        # 删除某一本书籍
                        def delete(self,request,id):
                            Book.objects.filter(pk=id).delete()
    
                            return Response()

    代码:

    views.py

    from django.shortcuts import render,HttpResponse
    import json
    from django.views import View
    from .models import *
    from app01.serialize import *
    from rest_framework.views import APIView
    from rest_framework.response import Response
    
    class PublishView(APIView):
    
        def get(self,request):
            #取数据
            print(request.GET)
            publish_list = Publish.objects.all()
    
            #序列化
            #方式一:
            #publish_list=list(Publish.objects.all().values("name","email"))
    
            #方式二:
            # from django.forms.models import model_to_dict
            # publish_list = Publish.objects.all()
            # temp=[]
            # for obj in publish_list:
            #     #利用这方法可以将字段和值对应组合成一个字典,一条数据一个字典。
            #     temp.append(model_to_dict(obj))
    
            #方式三
            # from django.core import serializers
            # publish_list = Publish.objects.all()
            # ret=serializers.serialize("json",publish_list)
    
            #方式四(restframework序列化)
            ps=PublishSerializers(publish_list,many=True)
            return HttpResponse(ps.data)
    
    
        def post(self,request):
            #原生request支持的操作
            # print(request.POST)
            # print(request.body)
            # print(type(request))
            from django.core.handlers.wsgi import WSGIRequest
    
    
            #新的request支持的操作
            print("request_data",request.data) #request_data {'name': 'jesi', 'email': '666@qq.com'}
            print("request_data_type",type(request.data))   #request_data_type <class 'dict'>
    
            return HttpResponse("POST")
    
    
    class PublishDetailView(APIView):
        def get(self,request,id):
            #单条数据查看
            publish=Publish.objects.filter(pk=id).first()
            ps=PublishModelSerializers(publish)
            return Response(ps.data)
    
        def put(self,request,id):
            #更新单条数据
            publish=Publish.objects.filter(pk=id).first()
    
            ps = PublishModelSerializers(publish,request.data)
            if ps.is_valid():
                ps.save()
                return Response(ps.data)
            else:
                return Response(ps.errors)
    
        def delete(self,request,id):
            Publish.objects.filter(pk=id).delete()
            return Response()
    
    
    
    class BookView(APIView):
        def get(self,request):
            book_list=Book.objects.all()
            # bs=BookSerializers(book_list,many=True)
            bs2=BookModelSerializers(book_list,many=True,context={'request': request})
            # return Response(bs.data)
            return Response(bs2.data)
    
    
        def post(self,request):
            #post请求的数据
            bs=BookModelSerializers(data=request.data)
            if bs.is_valid():
                bs.save()
                return Response(bs.data)
            else:
                return Response(bs.errors)
    
    
    class BookDetailView(APIView):
        def get(self,request,id):
            #单条数据查看
            book=Book.objects.filter(pk=id).first()
            bs=BookModelSerializers(book,context={'request': request})
            return Response(bs.data)
    
        def put(self,request,id):
            #更新单条数据
            book=Book.objects.filter(pk=id).first()
    
            bs = BookModelSerializers(book,request.data)
            if bs.is_valid():
                bs.save()
                return Response(bs.data)
            else:
                return Response(bs.errors)
    
    
    
        def delete(self,request,id):
            Book.objects.filter(pk=id).delete()
            return Response()
    View Code

    serialize.py

    # Author:Jesi
    # Time : 2018/10/5 11:29
    from app01.models import *
    from rest_framework import serializers   #这是rest_framework的序列化组件
    #为queryset(需要加many=True),model对象做序列化
    class PublishSerializers(serializers.Serializer):
        name =serializers.CharField()
        email=serializers.CharField()
    
    
    # Serializers
    class BookSerializers(serializers.Serializer):
        title = serializers.CharField(max_length=32)
        price = serializers.IntegerField()
        pub_date = serializers.DateField()
    
        publish = serializers.CharField(source="publish.email")  # 一对多字段使用source字段处理
    
        # 多对多使用下面字段,并且配一个方法,方法里面可自定义任意东西,可取作者表的名字。
        authors = serializers.SerializerMethodField()
    
        def get_authors(self, obj):
            temp = []
            for obj in obj.authors.all():
                temp.append(obj.name)
            return temp
    
    
    '''
    序列化BookSerializers(book_list,many=True)过程:
        temp=[]
        for obj in book_list:
            temp.append({
                "title":obj.title,
                "price":obj.price,
                "pub_date":obj.pub_date,
                                                            #"publish":str(publish),
                "publish":obj.publish.name,
                "authors":get_authors(obj)
    
            })
    '''
    
    class PublishModelSerializers(serializers.ModelSerializer):
        class Meta:
            model = Publish
            fields = "__all__"
    
    # ModelSerializers
    class BookModelSerializers(serializers.ModelSerializer):
        class Meta:
            model = Book
            fields = "__all__"
        publish=serializers.HyperlinkedIdentityField(
            view_name="publishdetail",
            lookup_field="publish_id",
            lookup_url_kwarg="id",
    
        )
    
        # publish = serializers.CharField(source="publish.pk")  # 一对多字段使用source字段处理
    
        #
        # #多对多使用下面字段,并且配一个方法,方法里面可自定义任意东西,可取作者表的名字。
        # authors=serializers.SerializerMethodField()
        # def get_authors(self,obj):
        #     temp=[]
        #     for obj in obj.authors.all():
        #         temp.append(obj.name)
        #     return temp
    
        # 因为上面自定制了字段,所以这个添加方法需要重写才可以。
        def create(self, validated_data):
            print(validated_data)
            book = Book.objects.create(title=validated_data["title"], price=validated_data["price"],
                                       pub_date=validated_data["pub_date"], publish_id=validated_data["publish"]["pk"])
            book.authors.add(*validated_data["authors"])
            return book
    View Code

    urls.py

    from django.contrib import admin
    from django.urls import path
    from django.conf.urls import url
    from app01 import views
    urlpatterns = [
        path('admin/', admin.site.urls),
        url(r'publishes/$', views.PublishView.as_view(),name="publish"),
        url(r'publishes/(?P<id>d+)/$', views.PublishDetailView.as_view(),name="publishdetail"),
        url(r'books/$', views.BookView.as_view(),name="books"),
        url(r'books/(d+)/$', views.BookDetailView.as_view(),name="bookdetail"),
    ]
    View Code
  • 相关阅读:
    SAP字符串处理
    ABAP更换请求
    Odoo安装教程12-创建新的插件模块之设置视图层第二讲
    Odoo安装教程12-创建新的插件模块之设置视图层第一讲
    Odoo安装教程11-创建新的插件模块之设置访问权限
    SAP是什么?-SAP 各模块概览
    SAP是什么?-SAP 各产品释义
    SAP版本演进及区别-S/4 HANA 与R3(ECC)
    Odoo安装教程12-创建新的插件模块之设置视图层第二讲
    Odoo安装教程12-创建新的插件模块之设置视图层第一讲
  • 原文地址:https://www.cnblogs.com/geogre123/p/9744937.html
Copyright © 2020-2023  润新知