• Django REST framework序列化


    Django REST framework序列化

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

    models部分

    from django.db import models
    
    
    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

    view部分

    from django.views import View
    from rest_framework.response import Response
    from app01.serializer import *
    from rest_framework.views import APIView
    
    
    class PublishView(APIView):
        def get(self, request):
    
            # 序列化方式
            # 方式1:
            # publish_list=list(Publish.objects.all().values("name","email"))
    
            # 方式2:
            # model_to_dict就是把一个model对象转换成字典
            # 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))
    
            # 方式3:
            # django的序列化组件,跟restful没关系,最简单的方式
            # from django.core import serializers
            # ret=serializers.serialize("json",publish_list)
    
            # 方式4:
            # DjangoRESTframework序列组件,详见serializer部分
            # 实例化一个序列化对象,传入要序列化的数据和many
            # many=True表示传入的是一个queryset,false是model对象
            publish_list = Publish.objects.all()
            ps = PublishModelSerializers(publish_list, many=True)
            # 取序列化后的数据
            return Response(ps.data)
     # restframework中get取数据
    # print("request.data", request.data)
    # print("request.data type", type(request.data))
    # print(request._request.GET)
    # print(request.GET)
     

    serializer部分

    from rest_framework import serializers
    from app01.models import *
    
    
    # 类1: 为queryset,model对象做序列化
    # 对哪些字段做序列化name = serializers.CharField() 这个字段序列化成什么类型
    class PublishSerializers(serializers.Serializer):
        name = serializers.CharField()
        email = serializers.CharField()
    
    
    # 类2: 上面的方式需要自己定义字段,faramework组件也有一个类似modelform的组件
    class PublishModelSerializers(serializers.ModelSerializer): class Meta: model = Publish fields = "__all__"
    # 类1中只设置了一些简单的字段,下面是一对多,多对多的字段时的方法 # 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 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(obj.publish), # obj.publish.name #"authors":obj.authors.all, "authors": get_authors(obj) }) '''

    ModelSerializer

    上面的类2就用的ModelSerializer

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

    处理POST请求

        def post(self, request):
            # 取数据,原生request支持的操作,如果contenttype其它的原生request不会帮你封装
            # print("POST",request.POST)
            # print("body",request.body)
            # # print(request)
            # print(type(request))
            # from django.core.handlers.wsgi import WSGIRequest
            #  新的request支持的操作
            # print("request.data",request.data)
            # print("request.data type",type(request.data))
    
                    # post请求的数据
            ps = PublishModelSerializers(data=request.data, many=False)
            if ps.is_valid():
                print(ps.validated_data)
                ps.save()  # create方法
                return Response(ps.data)
            else:
                return Response(ps.errors)

    重写save中的create方法

    class BookModelSerializers(serializers.ModelSerializer):
        class Meta:
            model = Book
            fields = "__all__"
        # authors=serializers.CharField(source="authors.all")
        authors = serializers.SerializerMethodField()
        def get_authors(self,obj):
            temp=[]
            for obj in obj.authors.all():
                temp.append(obj.name)
            return temp
        
    # 假如你上面自定义了字段的显示,就需要重写create方法了
    def create(self, validated_data):

    authors = validated_data.pop('authors') book
    =Book.objects.create(**validated_data)
    book.authors.add(*authors)
    return book

    单条数据的get、put、delete请求

    class PublishDetailView(APIView):
        def get(self, request, pk):
    
            publish = Publish.objects.filter(pk=pk).first()
            ps = PublishModelSerializers(publish)
            return Response(ps.data)
    
        def put(self, request, pk):
    # 先取出要更新的对象 publish
    = Publish.objects.filter(pk=pk).first() ps = PublishModelSerializers(publish, data=request.data) if ps.is_valid(): ps.save() return Response(ps.data) else: return Response(ps.errors) def delete(self, request, pk): Publish.objects.filter(pk=pk).delete() return Response()

    超链接API:Hyperlinked

    很多时候,我们就想一个字段的值是另一个字段的超链接,如下book表的publish字段就是publish表的超链接

    class BookModelSerializers(serializers.ModelSerializer):
        class Meta:
            model = Book
            fields = "__all__"
    
        publish = serializers.HyperlinkedIdentityField(
            # 你要找的url的别名
            view_name="detailpublish",
            # 含正则表达式如(d+)的话,下两步是把什么字段的内容,赋值给哪个分组命名
            lookup_field="publish_id",
            # 赋给什么分组命名
            lookup_url_kwarg="pk"
        )

    urls部分

    urlpatterns = [
    
        # View:view(request)=====APIView:dispatch()
        url(r'^publishes/$', views.PublishView.as_view(), name="publish"),
        url(r'^publishes/(?P<pk>d+)/$', views.PublishDetailView.as_view(), name="detailpublish"),
    
        # View:view(request)=====APIView:dispatch()
        url(r'^books/$', views.BookView.as_view(), name="books"),
        url(r'^books/(d+)/$', views.BookDetailView.as_view(), name="detailbook"),
    
    ]

    小结

    # 需要会的:
    restframework(Django)
    ----针对数据:json (1)Django的原生request: 浏览器 ------------- 服务器 "GET url?a=1&b=2 http/1.1 user_agent:Google contentType:urlencoded " "POST url http/1.1 user_agent:Google contentType:urlencoded a=1&b=2"       
          
          # post请求才有请求体,get没有请求体 request.body: a
    =1&b=2 request.POST: if contentType:urlencoded: # 才会给你封装 a=1&b=2----->{"a":1,"b":2}

    (
    2)restframework 下的APIView: (3) class PublishSerializers(serializers.Serializer): name=serializers.CharField() email=serializers.CharField() PublishSerializers(queryset,many=true) PublishSerializers(model_obj) 总结: 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() restframework 1 APIView 2 序列组件 3 视图、 4 组件(认证权限频率) 5 数据解析器 6 分页和Response
  • 相关阅读:
    三种常用的迭代搜索优化方法
    三种常用的迭代搜索优化方法
    颜色空间总结
    颜色空间总结
    卷积神经网络(CNN)
    卷积神经网络(CNN)
    在沉睡中站立起来
    在沉睡中站立起来
    Terence’s Stuff: Why do we do research?
    Terence’s Stuff: Why do we do research?
  • 原文地址:https://www.cnblogs.com/lxfpy/p/10978768.html
Copyright © 2020-2023  润新知