1. 程式人生 > >rest-framework組件 之 序列化

rest-framework組件 之 序列化

link 優化 操作 self. req elf clas erro django f

瀏覽目錄

  • 簡單使用

  • ModelSerializer

  • 提交post請求

  • 重寫save的create方法

  • 單條數據的get和put請求

  • 超鏈接API

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": "[email protected]", "id": 1},
    # {"name": "\u6843\u5b50\u51fa\u7248\u793e", "email": "[email protected]", "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": "[email protected]"},
    #  {"id": 2, "name": "\u6843\u5b50\u51fa\u7248\u793e", "email": "[email protected]"}]
    # 以上方式優化
    #     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": "[email protected]"}},
    #  {"model": "app01.publish", "pk": 2, "fields": {"name": "\u6843\u5b50\u51fa\u7248\u793e", "email": "[email protected]"}}]

我們來看一下如何用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":"[email protected]"},{"name":"桃子出版社","email":"[email protected]"}]

註意:如果是對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對象不能進行序列化。  

rest-framework組件 之 序列化