Django Rest Framework --- 序列化组件

一、序列化组件的作用

  在前后端分离开发时,前端与后端用来交互的数据的格式是一致的(数据格式为字符串的json数据),于是后端程序员在传递数据时,便要将数据封装成符合格式的数据,如果不借助方法,手动进行数据封装,会非常的浪费时间,在Django rest framework中的序列化组件帮我们解决了这个问题。

二、Django自带的序列化组件

from django.core import serializers
def test(request):
    book_list = Book.objects.all()    
    ret = serializers.serialize("json", book_list)
    return HttpResponse(ret)

三、rest framework 序列化之Serializer

  • models.py
from django.db import models

# Create your models here.
from django.db import models

# Book书籍:id  name  price  publish_date  publish(publish_id)
class Book(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=20)
    price = models.DecimalField(max_digits=5, decimal_places=2)
    publish_date = models.DateField()
    publish = models.ForeignKey(to='Publish', to_field='id', null=True, on_delete=models.SET_NULL, db_constraint=False)
    # 多对多关系字段,该字段不会再book表中形成字段,是用来创建关系表的
    author = models.ManyToManyField(to='Author', db_constraint=False)

    def test(self):
        return 22


# AuthorDetail作者详情: id  age  telephone  info
class AuthorDetail(models.Model):
    id = models.AutoField(primary_key=True)
    age = models.IntegerField()
    telephone = models.BigIntegerField()
    # 存大文本
    info = models.TextField()


# Author作者:id  name
class Author(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=20)
    # author_detail = models.ForeignKey(to='AuthorDetail', to_field='id', unique=True)
    author_detail = models.OneToOneField(to='AuthorDetail', to_field='id', null=True, on_delete=models.SET_NULL,
                                         db_constraint=False)


# Publish出版社:id  name  address
class Publish(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=20)
    address = models.CharField(max_length=64)
  • urls.py
from django.conf.urls import url
from django.contrib import admin
from app01.views import BooksView,BookView

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^Books/$', BooksView.as_view()),
    ]
  • MySerializer.py
from rest_framework import serializers
from rest_framework.exceptions import ValidationError
class BookSerializers(serializers.Serializer):
    id = serializers.CharField()
    name = serializers.CharField()
    price = serializers.DecimalField(max_digits=5,decimal_places=2)
    publish_date = serializers.DateField()
    publish = serializers.CharField(source='publish.name')
    # author = serializers.CharField(source='author.all') #获取author对象,结果为  "author": "<QuerySet [<Author: Author object>]>"
    author = serializers.SerializerMethodField()
    def get_author(self,obj):
        author_list = []
        for author in obj.author.all():
            author_list.append({
                "id":author.id,
                "name":author.name,
                "age":author.author_detail.age,
                "info":author.author_detail.info
            })
        return author_list

注意:

source 如果是字段,会显示字段,如果是方法,会执行方法,不用加括号(authors=serializers.CharField(source='authors.all'))如在模型中定义一个方法,直接可以在在source指定执行

  • views.py
from django.shortcuts import render
from rest_framework.views import APIView
from app01.models import Book
from app01.MySerializer import BookSerializers
from rest_framework.response import Response
# Create your views here.


class BooksView(APIView):
    def get(self,request):
        book_list = Book.objects.all()
        book_ser = BookSerializers(book_list,many=True)
        response = {"status":100,"message":"所有图书获取成功"}
        response['data'] = book_ser.data
        return Response(response)

    def post(self,request):
        book_ser = BookSerializers(data=request.data)
        if book_ser.is_valid():
            book_ser.save()
            response = {"status":100,"message":"创建图书成功"}
            response['data'] = book_ser.data
            print(response)
            return Response(response)
        else:
            response = {"status": 100, "message": book_ser.errors}
            return Response(response)
  • 结果
{
    "status": 100,
    "message": "所有图书获取成功",
    "data": [
        {
            "id": "1",
            "name": "红楼梦",
            "price": "88.00",
            "publish_date": "2019-02-25",
            "publish": "浙江出版社",
            "author": [
                {
                    "id": 1,
                    "name": "曹雪芹",
                    "age": 18,
                    "info": "曹雪芹简介"
                },
                {
                    "id": 2,
                    "name": "aaa",
                    "age": 19,
                    "info": "aaa简介"
                }
            ]
        },
        {
            "id": "2",
            "name": "亚索",
            "price": "199.00",
            "publish_date": "2019-01-29",
            "publish": "浙江出版社",
            "author": [
                {
                    "id": 2,
                    "name": "aaa",
                    "age": 19,
                    "info": "aaa简介"
                }
            ]
        }
    ]
}

四、rest framework序列化之ModelSerializer

class BookSerializers(serializers.ModelSerializer):
    class Meta:
        model = models.Book
        # fields = "__all__"
        fields=['nid','title','authors','publish']
        # exclude=('nid',)   #不能跟fields同时用
        # depth = 1    #深度控制,写 几 往里拿几层,层数越多,响应越慢,官方建议0--10之间,个人建议最多3层
    publish=serializers.SerializerMethodField()
    def get_publish(self,obj):
        return obj.publish.name
    authors=serializers.SerializerMethodField()
    def get_authors(self,obj):
        ret=obj.authors.all()
        ss=AuthorSerializer(ret,many=True)
        return ss.data

五、序列化组件之请求数据校验和保存功能

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

#————————
class BookView(APIView):

    def post(self, request):

        # 添加一条数据
        print(request.data)

        bs=BookSerializers(data=request.data)
        if bs.is_valid():
            bs.save()  # 生成记录
            return Response(bs.data)
        else:

            return Response(bs.errors)

六、图书的增删改查resful接口

  • view.py
class BooksView(APIView):
    def get(self, request, *args, **kwargs):
        response = {"status": 100, "message": "图书数据获取成功"}
        book_list = models.Book.objects.all()
        book_set = BookSerializers(book_list, many=True)
        response['data'] = book_set.data
        # return JsonResponse(response,safe=False,json_dumps_params={'ensure_ascii': False})
        return Response(response)
#
    def post(self,request):
        book_set = BookSerializers(data=request.data)
        print(book_set)
        if book_set.is_valid():
            response = {"status": 100, "message": "图书添加成功"}
            book_set.save()
            response['data'] = book_set.data
        else:
            response = {"status": 404, "message": book_set.errors}
            response['data'] = ""
        return Response(response)


class BookView(APIView):
    def get(self, request, pk, *args, **kwargs):
        book_obj = models.Book.objects.filter(pk=pk).first()
        book_set = BookSerializers(book_obj,many=False)
        if book_obj:
            response = {"status": 100, "message": "图书数据获取成功"}
            response['data'] = book_set.data
        else:
            response = {"status": 404, "message": "不存在该图书"}
            response['data'] = ""
        return Response(response)

    def delete(self,request,pk,*args,**kwargs):
        book_obj = models.Book.objects.filter(pk=pk)
        if book_obj:
            row = book_obj.delete()
            if row:
                response = {"status":200, "message": "数据删除成功"}
            else:
                response = {"status": 100, "message": "数据库数据删除失败"}
        else:
            response = {"status": 404, "message": "该图书不存在"}
        response['data'] = ''
        return Response(response)

    def put(self,request,pk,*args,**kwargs):
        book_obj = models.Book.objects.filter(pk=pk).first()
        print(book_obj)
        if book_obj:
            book_ser = BookSerializers(instance=book_obj,data=request.data)
            if book_ser.is_valid():
                book_ser.save()
                response = {"status": 100, "message": "图书修改成功"}
                response['data'] = book_ser.data
            else:
                response = {"status": 404, "message": book_ser.errors}
                response['data'] = ""
        else:
            response = {"status": 404, "message":"不存在该图书,无法修改"}
            response['data'] = ""
        return Response(response)

猜你喜欢

转载自www.cnblogs.com/846617819qq/p/10604673.html