zoukankan      html  css  js  c++  java
  • rest-framework组件 之 序列化

    浏览目录

     restful协议

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

    rest-framework

    针对数据:json数据。

    创建一个序列化类

    简单使用

    开发我们的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")
        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.views import View
    from .models import *
    class PublishView(View):
        def get(self,request):
            # 序列化方式一
            # publish_list=list(Publish.objects.all().values("id","name","email")) #queryset不能进行序列化,强转为list。
            # return HttpResponse(json.dumps(publish_list)) #转化为json字符串
        #    结果:[{"name": "u82f9u679cu51fau7248u793e", "email": "123@qq.com", "id": 1},
        # {"name": "u6843u5b50u51fau7248u793e", "email": "456@qq.com", "id": 2}]
    
        # 序列化方式二
        #     publish_list=Publish.objects.all()
        #     temp=[]
        #     for obj in publish_list:
        #         temp.append({
        #             "id":obj.pk,
        #             "name":obj.name,
        #             "email":obj.email
        #         })
        #     return HttpResponse(json.dumps(temp))
        # 结果:[{"id": 1, "name": "u82f9u679cu51fau7248u793e", "email": "123@qq.com"},
        #  {"id": 2, "name": "u6843u5b50u51fau7248u793e", "email": "456@qq.com"}]
        # 以上方式优化
        #     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  #django的序列化组件
            publish_list = Publish.objects.all()
            ret=serializers.serialize("json",publish_list)
            return HttpResponse(ret)
        # 结果:
        # [{"model": "app01.publish", "pk": 1, "fields": {"name": "u82f9u679cu51fau7248u793e", "email": "123@qq.com"}},
        #  {"model": "app01.publish", "pk": 2, "fields": {"name": "u6843u5b50u51fau7248u793e", "email": "456@qq.com"}}]

    我们来看一下如何用rest-framework进行序列化。

    from django.core import serializers
    from .models import *
    from rest_framework.response import Response
    from rest_framework import serializers
    from rest_framework.views import APIView
    # 为queryset,model对象做序列化
    # 实例化一个类
    class PublishSerializers(serializers.Serializer):
        # 需要序列化的字段
        name=serializers.CharField()
        email=serializers.CharField()
    class PublishView(APIView):
        def get(self,request):
            # 方式四:restframework
            publish_list = Publish.objects.all()
            ps = PublishSerializers(publish_list, many=True) #实例化一个对象
            return Response(ps.data)
    # 结果:[{"name":"苹果出版社","email":"123@qq.com"},{"name":"桃子出版社","email":"456@qq.com"}]

    注意:如果是对queryset做序列化,就要加many=True.如果是对model对象做序列化,就是many=False.默认为false,可以不用写。

    实例化的时候要是数据是一个 queryset 我们要加 many = True ret = PublishSerializers(publish_list, many=True) ret.data ------------------------------------拿到的是一个OrderDict。

    实例化的时候要是数据是一个model对象,many默认是一个False(可以不写) ret = PublishSerializers(obj) ret.data ------------------------------------拿到的是一个字典 

    ModelSerializer

    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 HttpResponse(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 HttpResponse(bs.errors)

    超链接API

    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"),
    ]
    

    总结:

    1、queryset对象不能进行序列化。  

  • 相关阅读:
    [NOIP2002 提高组] 均分纸牌
    洛谷 P1303 A*B Problem
    OpenJudge 1.6.5 年龄与疾病
    hdu 3340 线段树思路活用
    poj 2464 线段树统计区间..两棵树
    hdu 4419 矩形面积覆盖颜色
    经典动态规划 dp Rqnoj 57
    最基础二维线段树 hdu 1823 (简单)
    hdu 3564 线段树+dp
    spoj 1557 线段树 区间最大连续和 (不重复数)
  • 原文地址:https://www.cnblogs.com/gaoya666/p/9051521.html
Copyright © 2011-2022 走看看