ModelSerializer序列化器实战

上篇ModelSerializer序列化器做了一个小demo,演示了如何操作单表进行序列化和反序列化来实现五个API的使用,多表大差不差,这里对四个表写五个API接口

单表操作

单表操作序列化类demo:

序列化器类

# ModelSerializer和表模型有绑定关系
class BookSerializer1(serializers.ModelSerializer):
class Meta:
model = Book # 指定和哪个表有关系
# 所有字段
# fields = '__all__'
# 这里注意id字段是从表模型映射过来的,auto自增的,不传也可以
# 自定制的字段不传必须注册,在列表中
fields = ['id', 'title', 'price', 'price_info'] # 指定字段
extra_kwargs = {
'title': {'write_only': True, 'max_length': 8, 'min_length': 3}
}
# 指定序列化的字段:两种写法:在序列化类中写;models中写
price_info = serializers.SerializerMethodField()
def get_price_info(self, obj):
return "价格是:" + str(obj.price)
'''
注意:自定制字段如果和表模型获取到的字段是同名,那么自定制返回给前端的字段值就被自定制覆盖了,比如:
title = serializers.SerializerMethodField()
def get_title(self, obj):
return "书名是:" + str(obj.title)
''' # 局部和全局钩子,跟之前一样,但是要注意写在Meta外

视图类

from rest_framework.views import APIView
from .models import Book
from rest_framework.response import Response
from app01.serializer import BookSerializer1
class BookView1(APIView):
def get(self, request):
# 从数据库查数据,做序列化
book_list = Book.objects.all()
# 实例化类,传入初始化的参数,instance和many
'''
instance:要序列化的对象 qs,单个对象
many:如果是qs对象,many=True,如果是单个对象many=False
'''
ser = BookSerializer1(instance=book_list, many=True)
# ser.data使用模型类的对象得到序列化后的字典
return Response(ser.data) def post(self,request):
# 反序列化,保存到数据库使用data参数
deser = BookSerializer1(data=request.data)
# 校验数据
if deser.is_valid():
# 保存需要重写create方法,不然不知道存到哪个表
deser.save()
return Response(deser.data)
return Response({'code':101,'msg':'校验不通过','errors':deser.errors}) # 处理修改再写一个视图类,防止get冲突
class BookDetailView1(APIView):
def get(self,request,pk):
book = Book.objects.filter(pk=pk).first()
ser = BookSerializer1(instance=book) # 这里设置了主键值,单条记录many不需要写
return Response(ser.data)
def delete(self,request,pk):
res = Book.objects.filter(pk=pk).delete()
print(res) # (1, {'app01.Book': 1})
# res是影响的行数
if res[0]>0:
return Response({'code': 100, 'msg': '删除成功'})
else:
return Response({'code': 103, 'msg': '要删除的数据不存在'}) # 反序列化修改
def put(self,request,pk):
# 修改处理单条数据用过pk确定求改哪条数据
book = Book.objects.filter(pk=pk).first()
# 序列化器类实例化需要传入instance,data才表示修改
ser = BookSerializer1(instance=book,data=request.data)
if ser.is_valid():
# 重写update方法才能存入
ser.save()
return Response(ser.data)
return Response({'code':101,'msg':'校验未通过','error':ser.errors})

路由

path('books1/', views.BookView1.as_view()),
path('books1/<int:pk>', views.BookDetailView1.as_view()),

模型

from django.db import models
class Book(models.Model):
title = models.CharField(max_length=32)
price = models.DecimalField(max_digits=5,decimal_places=2)
authors = models.CharField(max_length=32)

多表操作

models.py

from django.db import models

# build four model tables

class Book(models.Model):
name = models.CharField(max_length=32)
price = models.DecimalField(decimal_places=2, max_digits=5)
publish = models.ForeignKey(to='Publish', on_delete=models.CASCADE)
authors = models.ManyToManyField(to='Author') def __str__(self):
return self.name # 自定制字段
@property
def publish_detail(self):
return {'name': self.publish.name, 'addr': self.publish.city} @property
def author_list(self):
l = []
print(self.authors.all()) # <QuerySet [<Author: Author object (1)>, <Author: Author object (2)>]>
for author in self.authors.all():
print(author.author_detail) # AuthorDetail object (1)
l.append({'name': author.name, 'age': author.age, 'addr': author.author_detail.addr})
return l class Author(models.Model):
name = models.CharField(max_length=32)
age = models.IntegerField()
author_detail = models.OneToOneField(to='AuthorDetail', on_delete=models.CASCADE) def __str__(self):
return self.name @property
def authordetail_info(self):
return {'phone':self.author_detail.telephone,'addr':self.author_detail.addr} class AuthorDetail(models.Model):
telephone = models.BigIntegerField()
addr = models.CharField(max_length=64) class Publish(models.Model):
name = models.CharField(max_length=32)
city = models.CharField(max_length=32)
email = models.EmailField()

serializer.py

from app01 import models
from rest_framework import serializers # 书序列化器
class BookSerializer(serializers.ModelSerializer):
class Meta:
# 指定和哪个表有关系
model = models.Book
# fields = '__all__'
fields = ['id','name','price','publish','authors','publish_detail','author_list']
# 将关联表的信息全部取出来,不推荐使用
# depth = 1 extra_kwargs = {
'publish':{'write_only':True},
'authors':{'write_only':True}
} # 作者序列化器
class AuthorSerializer(serializers.ModelSerializer):
class Meta:
# 指定和哪个表有关系
model = models.Author
# fields = '__all__'
fields = ['id', 'name', 'age', 'author_detail', 'authordetail_info']
extra_kwargs = {
'author_detail': {'write_only': True},
} # 作者详情序列化器
class AuthorDetailSerializer(serializers.ModelSerializer):
class Meta:
# 指定和哪个表有关系
model = models.AuthorDetail
fields = '__all__' # 出版社序列化器
class PublishSerializer(serializers.ModelSerializer):
class Meta:
# 指定和哪个表有关系
model = models.Publish
fields = '__all__'

views.py

from rest_framework.response import Response
from rest_framework.views import APIView from app01 import models
from app01 import serializer # 书视图类
class BookView(APIView):
def get(self, requets):
# 序列化
book_list = models.Book.objects.all()
# 序列化多条数据many=True
ser = serializer.BookSerializer(instance=book_list, many=True)
return Response(ser.data) def post(self, request):
# 获取反序列化数据
ser = serializer.BookSerializer(data=request.data)
if ser.is_valid():
# 校验通过存入数据库,不需要重写create方法了
ser.save()
return Response({'code': 100, 'msg': '新增成功', 'data': ser.data})
# 校验失败
return Response({'code': 101, 'msg': '校验未通过', 'error': ser.errors}) class BookViewDetail(APIView):
def get(self, request, pk):
book = models.Book.objects.filter(pk=pk).first()
ser = serializer.BookSerializer(instance=book)
return Response(ser.data) def put(self, request, pk):
book = models.Book.objects.filter(pk=pk).first()
# 修改,instance和data都要传
ser = serializer.BookSerializer(instance=book, data=request.data)
if ser.is_valid():
# 校验通过修改,不需要重写update
ser.save()
return Response({'code:': 100, 'msg': '修改成功', 'data': ser.data})
# 校验不通过
return Response({'code:': 102, 'msg': '校验未通过,修改失败', 'error': ser.errors}) def delete(self, request, pk):
models.Book.objects.filter(pk=pk).delete()
return Response({'code': 100, 'msg': '删除成功'}) # 作者视图类
class AuthorView(APIView):
def get(self, requets):
# 序列化
author_list = models.Author.objects.all()
# 序列化多条数据many=True
ser = serializer.AuthorSerializer(instance=author_list, many=True)
return Response(ser.data) def post(self, request):
# 获取反序列化数据
ser = serializer.AuthorSerializer(data=request.data)
if ser.is_valid():
# 校验通过存入数据库,不需要重写create方法了
ser.save()
return Response({'code': 100, 'msg': '新增成功', 'data': ser.data})
# 校验失败
return Response({'code': 101, 'msg': '校验未通过', 'error': ser.errors}) class AuthorViewDetail(APIView):
def get(self, request, pk):
book = models.Author.objects.filter(pk=pk).first()
ser = serializer.AuthorSerializer(instance=book)
return Response(ser.data) def put(self, request, pk):
book = models.Author.objects.filter(pk=pk).first()
# 修改,instance和data都要传
ser = serializer.AuthorSerializer(instance=book, data=request.data)
if ser.is_valid():
# 校验通过修改,不需要重写update
ser.save()
return Response({'code:': 100, 'msg': '修改成功', 'data': ser.data})
# 校验不通过
return Response({'code:': 102, 'msg': '校验未通过,修改失败', 'error': ser.errors}) def delete(self, request, pk):
models.Author.objects.filter(pk=pk).delete()
return Response({'code': 100, 'msg': '删除成功'}) # 作者详情视图类
class AuthorDetailView(APIView):
def get(self, requets):
# 序列化
author_list = models.AuthorDetail.objects.all()
# 序列化多条数据many=True
ser = serializer.AuthorDetailSerializer(instance=author_list, many=True)
return Response(ser.data) def post(self, request):
# 获取反序列化数据
ser = serializer.AuthorDetailSerializer(data=request.data)
if ser.is_valid():
# 校验通过存入数据库,不需要重写create方法了
ser.save()
return Response({'code': 100, 'msg': '新增成功', 'data': ser.data})
# 校验失败
return Response({'code': 101, 'msg': '校验未通过', 'error': ser.errors}) class OneAuthorViewDetail(APIView):
def get(self, request, pk):
book = models.AuthorDetail.objects.filter(pk=pk).first()
ser = serializer.AuthorDetailSerializer(instance=book)
return Response(ser.data) def put(self, request, pk):
book = models.AuthorDetail.objects.filter(pk=pk).first()
# 修改,instance和data都要传
ser = serializer.AuthorDetailSerializer(instance=book, data=request.data)
if ser.is_valid():
# 校验通过修改,不需要重写update
ser.save()
return Response({'code:': 100, 'msg': '修改成功', 'data': ser.data})
# 校验不通过
return Response({'code:': 102, 'msg': '校验未通过,修改失败', 'error': ser.errors}) def delete(self, request, pk):
models.AuthorDetail.objects.filter(pk=pk).delete()
return Response({'code': 100, 'msg': '删除成功'}) # 出版社视图类
class PublishView(APIView):
def get(self, requets):
# 序列化
author_list = models.Publish.objects.all()
# 序列化多条数据many=True
ser = serializer.PublishSerializer(instance=author_list, many=True)
return Response(ser.data) def post(self, request):
# 获取反序列化数据
ser = serializer.PublishSerializer(data=request.data)
if ser.is_valid():
# 校验通过存入数据库,不需要重写create方法了
ser.save()
return Response({'code': 100, 'msg': '新增成功', 'data': ser.data})
# 校验失败
return Response({'code': 101, 'msg': '校验未通过', 'error': ser.errors}) class PublishViewDetail(APIView):
def get(self, request, pk):
book = models.Publish.objects.filter(pk=pk).first()
ser = serializer.PublishSerializer(instance=book)
return Response(ser.data) def put(self, request, pk):
book = models.Publish.objects.filter(pk=pk).first()
# 修改,instance和data都要传
ser = serializer.PublishSerializer(instance=book, data=request.data)
if ser.is_valid():
# 校验通过修改,不需要重写update
ser.save()
return Response({'code:': 100, 'msg': '修改成功', 'data': ser.data})
# 校验不通过
return Response({'code:': 102, 'msg': '校验未通过,修改失败', 'error': ser.errors}) def delete(self, request, pk):
models.Publish.objects.filter(pk=pk).delete()
return Response({'code': 100, 'msg': '删除成功'})

urls.py

from django.contrib import admin
from django.urls import path from app01 import views urlpatterns = [
path('admin/', admin.site.urls),
# 书
path('books/', views.BookView.as_view()),
path('books/<int:pk>', views.BookViewDetail.as_view()), # 作者
path('authors/', views.AuthorView.as_view()),
path('authors/<int:pk>', views.AuthorViewDetail.as_view()), # 作者详情
path('authorsdetail/', views.AuthorDetailView.as_view()),
path('authorsdetail/<int:pk>', views.OneAuthorViewDetail.as_view()), # 出版社
path('publish/', views.PublishView.as_view()),
path('publishdetail/<int:pk>', views.PublishViewDetail.as_view()),
]

Postman自行测试,我测了测都能用,有问题望指正~

ModelSerializer序列化器实战的更多相关文章

  1. DRF框架之ModelSerializer序列化器

    ModelSerializer是Serializer的子类,序列化和反序列化跟Serializer一样. ModelSerializer与常规的Serializer相同,但提供了: 基于模型类自动生成 ...

  2. 模型类序列化器ModelSerializer

    定义 比如我们创建一个BookInfoSerializer class BookInfoSerializer(serializers.ModelSerializer): ""&qu ...

  3. 序列化器:ModelSerializer

    ModelSerializer 类提供了一个快捷方式,可让你基于 Models 自动创建一个 Serializer 类,其中的字段与模型类字段对应. ModelSerializer 类与常规 Seri ...

  4. DRF 序列化器-Serializer (2)

    作用 1. 序列化,序列化器会把模型对象转换成字典,经过response以后变成json字符串 2. 完成数据校验功能 3. 反序列化,把客户端发送过来的数据,经过request以后变成字典,序列化器 ...

  5. 一: DRF web应用框架基础,及序列化器的使用

    ---恢复内容开始--- 一: web 应用模式(有两种) 1: 前后端不分离(前端从后端直接获取数据) 2: 前后端分离 二: api 接口 原因一: 为了在团队内部形成共识.防止个人习惯差异引起的 ...

  6. DRF中的序列化器

    DRF中的序列化器详细应用   视图的功能:说白了就是接收前端请求,进行数据处理 (这里的处理包括:如果前端是GET请求,则构造查询集,将结果返回,这个过程为序列化:如果前端是POST请求,假如要对数 ...

  7. serializers 序列化器里面进行 校验等

    一.第一版(一般不用) # 声明序列化器from rest_framework import serializersfrom djangoDome.models import Book class P ...

  8. drf序列化器serializers.SerializerMethodField()的用法

    问题描述: 为什么DRF中有时候返回的json中图片是带域名的,有时候是不带域名的呢? 解析: 带域名的结果是在view中对模型类序列化的,DRF在序列化图片的时候 会检查上下文有没有request, ...

  9. drf序列化器的实例

    应用目录结构: views.py from django.shortcuts import render # Create your views here. from django.views imp ...

随机推荐

  1. 【C# 线程】线程局部存储(TLS) 实战部分 ThreadStatic|LocalDataStoreSlot|ThreadLocal<T>

    往袋子里面装苹果 错误案例示范 关于C#多线程的文章,大部分都在讨论线程的起停或者是多线程同步问题.多线程同步就是在不同线程中访问同一个变量(一般是线程工作函数外部的变量),众所周知在不使用线程同步的 ...

  2. 【windows 访问控制】十、词汇列表和对应C#类、枚举、命名空间

    principals:主体 主体包含标识(identity 对用来来说就是用户名,对程序来说就是SID)和用户角色(role 对用户来说就是 组名 对程序来说就是组SID)subject:主体.主语i ...

  3. MailKit和MimeKit 收发邮件

    新建项目,引用MailKit和MimeKit NuGet包 using CommonTool.MailKit; using System; using System.Collections.Gener ...

  4. SpringBoot入门二:与Mybatis整合

    一.编程步骤 1.引入依赖 springboot相关依赖(略).mybatis-spring-boot-starter.mysql.druid.lombook <dependency> & ...

  5. 基于NET 6.0 封装的 Fast.Framework

    Fast Framework 项目地址 https://gitee.com/China-Mr-zhong/Fast.Framework Author Mr-zhong Wechat 850856667 ...

  6. TCC分布式事框架务详解

    之前网上看到很多写分布式事务的文章,不过大多都是将分布式事务各种技术方案简单介绍一下.很多朋友看了还是不知道分布式事务到底怎么回事,在项目里到底如何使用. 所以这篇文章,就用大白话+手工绘图,并结合一 ...

  7. luoguP6619 [省选联考 2020 A/B 卷]冰火战士(线段树,二分)

    luoguP6619 [省选联考 2020 A/B 卷]冰火战士(线段树,二分) Luogu 题外话1: LN四个人切D1T2却只有三个人切D1T1 很神必 我是傻逼. 题外话2: 1e6的数据直接i ...

  8. onGUI常用脚本学习(引用)

    https://blog.csdn.net/Hannah1221/article/details/101941174?spm=1001.2101.3001.6650.3&utm_medium= ...

  9. 入门级的Makefile制作dynamic lib

    代码文件结构: . ├── dynamiclib_add.c ├── dynamiclib_mul.c ├── dynamiclibs.h ├── libs └── Makefile 1 direct ...

  10. 用腾讯云Gogs搭建私有git服务器

    前言 经常有需要写不能公开代码的项目,所以只好自己搭建一个私人的git服务器 Gogs的好处在于比Gitlib轻量化了好多,而且是国人写的,官方主页也是中文的 Gogs首页 腾讯云服务器配置: Ubu ...