Django 原生 serializer (序列化)

  1. 导入模块  from django.core.serializers import serialize
  2. 获取 queryset
  3. 对 queryset 进行序列化
  4. 将序列化之后的数据,返回给客户端

首先,设计url, 先只定义GET和POST接口

from django.urls import path

from DrfOne import views

urlpatterns = [
path('books/', views.BookView.as_view()),
]

再定义几个models

 from django.db import models

 class Publish(models.Model):
nid = models.AutoField(primary_key=True)
name = models.CharField("出版社名", max_length=32)
address = models.CharField("出版社位置", max_length=32)
email = models.EmailField("邮箱") def __str__(self):
return self.name class Author(models.Model):
nid = models.AutoField(primary_key=True)
name = models.CharField("姓名", max_length=31)
age = models.IntegerField("年龄") def __str__(self):
return self.name class Book(models.Model):
nid = models.AutoField(primary_key=True)
title = models.CharField("书名", max_length=32)
price = models.DecimalField("价格", max_digits=5, decimal_places=2)
publish = models.ForeignKey(to="Publish", on_delete=models.CASCADE)
authors = models.ManyToManyField(to="Author") def __str__(self):
return self.title

models.py

使用

from django.shortcuts import render, HttpResponse
from rest_framework.views import APIView
# 1.导入模块
from django.core.serializers import serialize class CourseView(APIView):
def get(self, request):
# 2.获取queryset
course_obj = models.Course.objects.all()
# 3.序列化
serialized_data = serialize("json", course_obj)
print(serialized_data)
# 4.将序列化之后的数据返回
return HttpResponse(serialized_data)

序列化组件serializer的使用

Serializer

GET接口设计(获取所有数据)

  1. 导入模块
  2. 建立一个序列化类
  3. 获取 queryset
  4. 开始序列化
  5. 获取序列化后的数据,返回给客户端
from rest_framework.views import APIView
# 1.导入模块
from rest_framework import serializers
# drf重新封装之后的Response基于TemplateResponse类型,
# 可以将未处理的内容通过内容协商来决定返回给客户端的正确内容形式
from rest_framework.response import Response from DrfOne import models # 2.创建一个序列化类,字段类型不一定要跟models的字段一样
class BookSerializer(serializers.Serializer):
# id一般情况不用写
# nid = serializers.CharField(max_length=32)
title = serializers.CharField(max_length=32)
price = serializers.DecimalField(max_digits=5, decimal_places=2)
# 外键字段,显示__str__方法的返回值
publish = serializers.CharField() # 多对多字段, 执行get_字段名 方法,手动获取数据
author_list = serializers.SerializerMethodField() def get_author_list(self, book_obj):
# 第二个参数随意
author_list = list()
for author in book_obj.authors.all():
author_list.append(author.name)
return author_list class BookView1(APIView):
def get(self, request):
# 3.获取queryset
book_objs = models.Book.objects.all()
# 4.通过序列化类进行序列化
serialized_obj = BookSerializer(book_objs, many=True)
# print(serialized_obj) # 5.获取序列化之后的数据,返回给客户端
return Response(serialized_obj.data)

POST接口设计

  1. 导入模块
  2. 建立一个序列化类
  3. 获取客户端请求数据
  4. 开始序列化
  5. 写入数据库
  6. 将插入的对象返回给客户端

请注意,因为多对多关系字段是我们自定义的,而且必须这样定义,返回的数据才有意义,而用户插入数据的时候,serializers.Serializer没有实现create,我们必须手动插入数据,就像这样:

# 1.导入模块
from rest_framework import serializers
from rest_framework.views import APIView
# drf重新封装之后的Response基于TemplateResponse类型,
# 可以将未处理的内容通过内容协商来决定返回给客户端的正确内容形式
from rest_framework.response import Response from DrfOne import models # 2.创建一个序列化类,字段名和字段类型不一定要跟models的字段一样
class BookSerializer(serializers.Serializer):
# id一般情况不用写
# nid = serializers.CharField(max_length=32)
title = serializers.CharField(max_length=32)
price = serializers.DecimalField(max_digits=5, decimal_places=2)
# 外键字段,显示__str__方法的返回值
publish = serializers.CharField()
# 仅读字段read_only=True,source是该字段显示出版社地址
publish_address = serializers.CharField(max_length=32, read_only=True, source="publish.address")
publish_email = serializers.CharField(max_length=32, read_only=True, source="publish.email") # 多对多字段, 执行get_字段名 方法,手动获取数据
author_list = serializers.SerializerMethodField() def get_author_list(self, book_obj):
# 第二个参数随意
author_list = list()
for author in book_obj.authors.all():
author_list.append(author.name)
return author_list def create(self, validated_data):
# 创建时调用
validated_data['publish_id'] = validated_data.pop('publish')
book = models.Book.objects.create(**validated_data)
return book def update(self, instance, validated_data):
# 更新数据会调用该方法
instance.title = validated_data.get('title', instance.title)
instance.publishDate = validated_data.get('publishDate', instance.publishDate)
instance.price = validated_data.get('price', instance.price)
instance.publish_id = validated_data.get('publish', instance.publish.nid) instance.save() return instance class BookView(APIView):
def get(self, request):
pass def post(self, request):
# 3.获取客户端的数据
client_data = request.data
# 4.序列化,默认many=False单条数据
verified_data = BookSerializer(data=client_data)
# 对数据进行验证
if verified_data.is_valid():
# 5.写入数据库
book = verified_data.save()
authors = models.Author.objects.filter(nid__in=request.data["authors"])
book.authors.add(*authors)
# 6.将插入的对象数据返回
return Response(verified_data.data)
# 验证失败返回错误信息
return Response(verified_data.errors)

从上面可以看出:

  1.  serializers.Serializer 无法插入数据,只能自己实现。
  2. 字段太多,不能自动序列化

这样就会非常复杂化程序,如果我希望序列化类自动插入数据呢?

这也就有了 ModelSerializer

ModelSerializer

ModelSerializer  类似于form组件里的 ModelForm

from rest_framework import serializers
from rest_framework.views import APIView class BookSerializer(serializers.ModelSerializer):
class Meta:
model = models.Book
fields = "__all__" extra_kwargs = {
# 仅写
"publish": {'write_only': True},
"authors": {'write_only': True},
} publish_name = serializers.CharField(max_length=32, read_only=True, source="publish.name")
publish_address = serializers.CharField(max_length=32, read_only=True, source="publish.address")
author_name = serializers.SerializerMethodField() def get_author_name(self, book_obj):
author_list = list()
for author in book_obj.authors.all():
# 注意列表添加字段,author.name而不是author
author_list.append(author.name)
return author_list

这样看起来简单多了!

get(单条数据)、put(改)、delete(删) 接口设计

设计url

from django.urls import path, re_path

from DrfOne import views

urlpatterns = [
path('books/', views.BookView.as_view()),
re_path("books/(\d+)/", views.BookFilterView.as_view()),
]

视图设计

class BookFilterView(APIView):
def get(self, request, nid):
# 获取queryset
book_obj = models.Book.objects.get(pk=nid)
# 序列化
serialized_data = BookSerializer(book_obj)
# 返回数据
return Response(serialized_data.data) def put(self, request, nid):
# 获取queryset
book_obj = models.Book.objects.get(pk=nid)
# 序列化, 根据instance是确认是否是更新, many默认为False可以不写
verified_data = BookSerializer(data=request.data, instance=book_obj, many=False)
if verified_data.is_valid():
verified_data.save()
# 返回数据
return Response(verified_data.data)
return Response(verified_data.errors) def delete(self, request, nid):
models.Book.objects.get(pk=nid).delete() return Response("")

~>.<~

最新文章

  1. 【续集】在 IIS 中部署 ASP.NET 5 应用程序遭遇的问题
  2. COGS103&amp;tyvj1899 [NOIP2002]矩形覆盖
  3. javascript中的事件委托
  4. 【初级为题,大神绕道】The app icon set named "AppIcon" did not have any applicable content 错误#解决方案#
  5. Sql Server服务远程过程调用失败解决
  6. 109. Convert Sorted List to Binary Search Tree
  7. ASP.NET的SEO:正则表达式
  8. 用时间复杂度为n的方法找出水王
  9. CSS3伪类选择器
  10. Spring Cloud介绍 Spring Cloud与Dubbo对比
  11. HDOJ 1215 七夕节
  12. 一些常用的操作MySQL数据库的sql语句
  13. MySQL创建用户与授权
  14. 【Halum操作-UVA 11478】
  15. Navicat连接阿里云服务器Linux下的Mysql
  16. selenium--鼠标事件
  17. SQL分组函数
  18. spring-mvc默认首页配置
  19. 使用SSH远程登陆Linux
  20. django具体操作(七)

热门文章

  1. ESP8266 智能配网 断电重连
  2. 一个自动修正数据时间和补全缺失数据的MapReduce程序
  3. java基础开发环境安装(全)
  4. mysql的属性zerofill
  5. Ubuntu网络network eth0配置 | ubuntu network configuration
  6. java.lang.String 的 + 号操作到底做了什么事情?
  7. 记一次安卓app上线应用宝
  8. (四十五)golang--反射
  9. css三大特效之优先级
  10. PHP基于Redis实现轻量级延迟队列