这里的介绍的serializers.ModelSerializer就和我们之前学习的modelform一样

serializers.ModelSerializer如下几个功能

1、序列化queryset数据

2、反序列化json数据,将反序列化后的数据转换成model对象

3、反序列化的时候还是可以对数据做校验

4、如果合法,可以调用sava方法进行post或者put请求操作

5、如果不合法,则返回错误

下面我们进入serializers.ModelSerializer的学习

首先写一个modelserializer的类,不知道看官有没有发现,和我们之前学的modelform几乎完全一样

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

  

然后我们在get请求中,如何通过上面的类序列化queryset对象,可以看到直接之前的serializer类替换为modelserializer类就可以了

from rest_framework.views import APIView
from rest_framework.response import Response
class Book_cbv(APIView):
def get(self,request):
query_list = models.Book.objects.all()
# bs = book_serializers(query_list,many=True)
bs = bookmodelserializer(query_list,many=True) print(dir(serializers))
return Response(bs.data)

  

通过postman发送get请求,我们看下受到的信息,我们看到一对多字段和多对多字段均为所对应对象的id,我们可以定制化的显示我们需要显示的信息,但是这里暂时不做讲解,在博客的后面我们在做讲解

上面处理完了get请求,下面我们在处理一下post请求,我们通过postman发送json信息,然后通过modelserializerlizer直接保存信息,post请求处理的代码如下

如何数据有效,则保存数据,这个也和modelform非常的类型,可以说是完全一样

    def post(self,request):
bs = bookmodelserializer(data=request.data) if bs.is_valid():
print(bs.validated_data)
bs.save()
return Response(bs.data)
else:
return Response(bs.errors)

 

下面我们通过postman发送post请求,测试一下

 

发送完post请求,我们看下返回的结果,将我们的新增的数据返回了

至此,modelserializar的基本用法我们就讲完了

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

下面我们开始定制化的处理

首先,在get请求中,对于一对多和多对多的字段,我们想定制化的显示,那么我们就可以这样做

class bookmodelserializer(serializers.ModelSerializer):
class Meta:
model = models.Book
fields = "__all__"
# 一对多,关联指定的对象,然后显示指定对象的字段 book_publish = serializers.CharField(source="book_publish.id") book_auther = serializers.SerializerMethodField()
def get_book_auther(self,obj): s = ""
for i in obj.book_auther.all():
s = s + i.auther_name + "|" s = s.rstrip("|")
return s

  

重点是这里,就是serializer中处理一对多和多对多的代码拿过来就可以了

下面我们通过postman发送get请求,看下前端的显示效果,看到效果,已经实现了我们的想要的结果

上面解决了定制化的处理get请求,那么post请求行不行呢?

我们直接使用postman来做一下测试

我们看到有报错,其实的modelserializer这个类的create方法无法处理这种定制的话的数据

下面的是modelserializer类的create方法

    def create(self, validated_data):
"""
We have a bit of extra checking around this in order to provide
descriptive messages when something goes wrong, but this method is
essentially just: return ExampleModel.objects.create(**validated_data) If there are many to many fields present on the instance then they
cannot be set until the model is instantiated, in which case the
implementation is like so: example_relationship = validated_data.pop('example_relationship')
instance = ExampleModel.objects.create(**validated_data)
instance.example_relationship = example_relationship
return instance The default implementation also does not handle nested relationships.
If you want to support writable nested relationships you'll need
to write an explicit `.create()` method.
"""
raise_errors_on_nested_writes('create', self, validated_data) ModelClass = self.Meta.model # Remove many-to-many relationships from validated_data.
# They are not valid arguments to the default `.create()` method,
# as they require that the instance has already been saved.
info = model_meta.get_field_info(ModelClass)
many_to_many = {}
for field_name, relation_info in info.relations.items():
if relation_info.to_many and (field_name in validated_data):
many_to_many[field_name] = validated_data.pop(field_name) try:
instance = ModelClass._default_manager.create(**validated_data)
except TypeError:
tb = traceback.format_exc()
msg = (
'Got a `TypeError` when calling `%s.%s.create()`. '
'This may be because you have a writable field on the '
'serializer class that is not a valid argument to '
'`%s.%s.create()`. You may need to make the field '
'read-only, or override the %s.create() method to handle '
'this correctly.\nOriginal exception was:\n %s' %
(
ModelClass.__name__,
ModelClass._default_manager.name,
ModelClass.__name__,
ModelClass._default_manager.name,
self.__class__.__name__,
tb
)
)
raise TypeError(msg) # Save many-to-many relationships after the instance is created.
if many_to_many:
for field_name, value in many_to_many.items():
field = getattr(instance, field_name)
field.set(value) return instance

  

因为我们的对象是继承了modelserializer类,所以我们重写一下create方法,就可以解决这个问题,因为如果我们的类中有create方法,会优先调用我们自己的create方法,只有当我们的类中没有create方法,才会去调用父类的create方法

首先我们在自己的类中定义一个create方法,先打印参数看看

class bookmodelserializer(serializers.ModelSerializer):
class Meta:
model = models.Book
fields = "__all__"
# 一对多,关联指定的对象,然后显示指定对象的字段
def create(self, validated_data):
print(validated_data) book_publish = serializers.CharField(source="book_publish.id") book_auther = serializers.SerializerMethodField()
def get_book_auther(self,obj): s = ""
for i in obj.book_auther.all():
s = s + i.auther_name + "|" s = s.rstrip("|")
return s

  

create方法我们下截图出来

我们再次通过postman发送post请求,看下打印的结果

这里我无论如何怎么处理,在新的create方法中均无法打印出book_auther的数据,我也是很纳闷

无论我在上面的函数中返回一个字符串,还是一个list,都不行

上面这一行是reqeust.data中的数据,下面这一行是validated_data中的数据

那么我暂时把多对多中的定制化处理注销掉,用默认的方式显示把

class bookmodelserializer(serializers.ModelSerializer):
class Meta:
model = models.Book
fields = "__all__"
# 一对多,关联指定的对象,然后显示指定对象的字段
def create(self, validated_data):
print("validated_data",validated_data)
# models.Book.objects.create(
# book_name = validated_data
# )
book_publish = serializers.CharField(source="book_publish.id") # book_auther = serializers.SerializerMethodField()
# def get_book_auther(self,obj):
#
# s = []
# for i in obj.book_auther.all():
# s.append(i)
#
#
# return s

  

这次我们通过postman发送post请求

这次validated_data中就有book_auther信息就了

然后我们调用create方法在数据库中创建数据就可以了

class bookmodelserializer(serializers.ModelSerializer):
class Meta:
model = models.Book
fields = "__all__"
# 一对多,关联指定的对象,然后显示指定对象的字段
def create(self, validated_data):
print("validated_data",validated_data)
ret = models.Book.objects.create(
book_name = validated_data["book_name"],
book_price = validated_data["book_price"],
book_publish_id = validated_data["book_publish"]["id"]
)
ret.book_auther.add(*validated_data["book_auther"]) return ret

  

这个时候我们在通过postman发送post请求,可以看到创建数据成功了

至于定制化的多对多字段,我下来在研究一下,今天太晚了,明天还得上班!

												

Django的rest_framework的序列化组件之serializers.ModelSerializer介绍的更多相关文章

  1. Django的rest_framework的序列化组件之序列化多表字段的方法

    首先,因为我们安装了restframework,所以我们需要在django的settings中引入restframework INSTALLED_APPS = [ 'django.contrib.ad ...

  2. rest_framework之序列化组件

    什么是rest_framework序列化? 在写前后端不分离的项目时: 我们有form组件帮我们去做数据校验 我们有模板语法,从数据库取出的queryset对象不需要人为去转格式 当我们写前后端分离项 ...

  3. Django Rest Framework(2)-----序列化详解(serializers)

    REST framework中的序列化类与Django的Form和ModelForm类非常相似.我们提供了一个Serializer类,它提供了一种强大的通用方法来控制响应的输出,以及一个ModelSe ...

  4. django自带的序列化组件

    1.什么是序列化组件 在django中,自带一个序列化组件,它是用来将数据进行整理.转化成特定的为一个特定的格式(比如json数据格式),然后传输给前端,以便前端对数据进行处理操作. 2.为什么要用序 ...

  5. Django的rest_framework的分页组件源码分析

    前言: 分页大家应该都很清楚,今天我来给大家做一下Django的rest_framework的分页组件的分析:我的讲解的思路是这样的,分别使用APIview的视图类和基于ModelViewSet的视图 ...

  6. Django框架第九篇--Django和Ajax、序列化组件(serializers)、自定义分页器、模型表choice参数

    Django和Ajax 一.什么是Ajax AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步的Javascript和XML”.即使用Javascript语 ...

  7. Django之REST_framework 框架基本组件使用

    快速实例 快速实例: 点击查看官方文档 阅读推荐:点击查看 序列化 创建一个序列化类 简单使用 开发我们的Web API的第一件事是为我们的Web API提供一种将代码片段实例序列化和反序列化为诸如j ...

  8. Django1.0和2.0中的rest_framework的序列化组件之超链接字段的处理

    大家看到这个标题是不是有点懵逼,其实我就是想要一个这样的效果 比如我get一条书籍的数据,在一对多的字段中我们显示一个url,看起来是不是很绚! 下面我们就来实现这么一个东西 首先我们一对多字段中的一 ...

  9. Django的rest_framework的权限组件和频率组件源码分析

    前言: Django的rest_framework一共有三大组件,分别为认证组件:perform_authentication,权限组件:check_permissions,频率组件:check_th ...

随机推荐

  1. Java中==号与equals()方法的区别

    String str1 = new String("abc"); String str2 = new String("abc"); System.out.pri ...

  2. 2018SDIBT_国庆个人第一场

    A - Turn the Rectangles CodeForces - 1008B There are nn rectangles in a row. You can either turn eac ...

  3. spark使用scala读取Avro数据(转)

    这是一篇翻译,原文来自:How to load some Avro data into Spark. 首先,为什么使用 Avro ? 最基本的格式是 CSV ,其廉价并且不需要顶一个一个 schema ...

  4. 9.mysql-存储过程.md

    目录 创建 创建 -- 创建存储过程 DELIMITER $ -- 声明存储过程的结束符 CREATE PROCEDURE pro_test() --存储过程名称(参数列表) BEGIN -- 开始 ...

  5. 做好Unity4.x开发项目规划

    1. 是否要用lua 2. (对于需操作的游戏)客户端游戏如何做战斗验证 下面列举小坑吧.不建议都绕开,毕竟没有那么多时间做前期调研的. 对应版本Unity4.x 1. 客户端程序层面 总的来说C#超 ...

  6. TMG2010安装配置细节设定

    TMG2010最适合的操作系统是Win2008R2,不支持Win2012,可能是因为发布Win2012系统时,微软已经决定废弃TMG改为支持UAG了吧. 在Win2012下安装TMG2010,运行TM ...

  7. Ubuntu中更改所有子文件和子目录所有者权限

    转自:http://www.linuxidc.com/Linux/2015-03/114695.htm Ubuntu中有两个修改命令可以用到,「change mode」&「change own ...

  8. linux下卸载自带的JDK和安装想要的JDK

    卸载 1.卸载用 bin文件安装的JDK方法:      删除/usr/java目录下的所有东西 2.卸载系统自带的jdk版本方法: 查看自带的jdk: #rpm -qa | grep gcj 看到如 ...

  9. linux配置虚拟主机

    linux 下怎么配置虚拟主机 linux 下怎么配置虚拟主机,在网上找到N个资料都是高手们随便说几句,都没怎么说清楚.问题:  我把域名(bs.jxiop.com)指向了 68.10.140.10 ...

  10. zxing解析带logo二维码会报com.google.zxing.NotFoundException

    参考原文:https://blog.csdn.net/cyl1226541/article/details/70557232 //复杂模式,开启PURE_BARCODE模式(☆☆☆) HINTS.pu ...