这里的介绍的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. Centos6与Centos7防火墙设置与端口开放的方法

    Centos升级到7之后,内置的防火墙已经从iptables变成了firewalld.所以,端口的开启还是要从两种情况来说明的,即iptables和firewalld.更多关于CentOs防火墙的最新 ...

  2. JSONArray 遍历

    JSONArray 遍历   刚遇到一个接接口任务,发现其中返回数据中,是个字符串数组,数组中就是单个json形式的内容,其实应该也可以称这种数据叫做json数组吧,只不过是字符串形式.而我需要的是将 ...

  3. python中pop()函数的用法

    pop() 函数用于移除列表中的一个元素(默认最后一个元素),并且返回该元素的值. 语法:list.pop(obj=list[-1]) //默认为 index=-1,删除最后一个列表值. obj -- ...

  4. html:meta

    <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale= ...

  5. BerOS File Suggestion(stl-map应用)

    Polycarp is working on a new operating system called BerOS. He asks you to help with implementation ...

  6. Sql Server 中由数字转换为指定长度的字符串

    一个列的数据类型是 int ,从 1 开始自动增长,另一个列是字符串,现在想把 int 列转换成 九个字符,比如 1 转换后就是 000000001 ,添到字符串列,怎么实现呢? set @imaxU ...

  7. shell命令中用source 和sh(或者bash)执行脚本的区别,以及export的作用

    用户登录到Linux系统后,系统将启动一个用户shell,我们暂且称这个shell为shell父. 在这个shell父中,可以使用shell命令或声明变量,也可以创建并运行shell脚本程序. 当使用 ...

  8. Android构建项目时出现的小bug们(2018年5月19日19:31:20)

    问题详情 Error:Execution failed for task ':app:preDebugAndroidTestBuild'. > Conflict with dependency ...

  9. python函数基础:调用内置函数&定义函数

    调用内置函数 有很多内置函数,在使用中需要积累.这里只举两个例子: 分别调用abs和数据类型转换,注意当入参类型错误时候会报错 ''' print('abs(-100)') abs(-100) pri ...

  10. easyui-datebox 只能获取当前日期以前的日期

    <td> <input id="happenTimes" name="happenTimes" class="easyui-date ...