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": "\u82f9\u679c\u51fa\u7248\u793e", "email": "123@qq.com", "id": 1},
    # {"name": "\u6843\u5b50\u51fa\u7248\u793e", "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": "\u82f9\u679c\u51fa\u7248\u793e", "email": "123@qq.com"},
    #  {"id": 2, "name": "\u6843\u5b50\u51fa\u7248\u793e", "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": "\u82f9\u679c\u51fa\u7248\u793e", "email": "123@qq.com"}},
    #  {"model": "app01.publish", "pk": 2, "fields": {"name": "\u6843\u5b50\u51fa\u7248\u793e", "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对象不能进行序列化。  

posted @ 2018-05-29 10:36  高~雅  阅读(413)  评论(0编辑  收藏  举报