基本使用

-序列化
-对象,转成json格式
用drf的序列化组件
  -定义一个类继承class BookSerializer(serializers.Serializer):
  -写字段,如果不指定source,字段名必须跟数据库字段名对应(source指定的值跟字段名不能重复)
  -source还可以指定方法
  -publish=serializers.SerializerMethodField()
def get_publish(self,obj):
obj.publish
#obj.authors.all() -Serializer
-ModelSerializer
class Meta:
# 指定表模型
model = models.Book
# 序列化所有字段
fields = '__all__'
# 只想序列化title和id这俩字段
# fields = ['title', 'id']
# exclude 和fields 不要连用
# exclude = ['title']
depth=1
         
          -反序列化:
            -保存
              ser=BookSer(data=传过来的字典)
              if ser.is_valid()
                ser.save()
            -取校验通过的数据:
              ser.data
            -修改
              ser=BookSer(data=传过来的字典,instance=要修改的对象)
              if ser.is_valid()
                ser.save()
              else:
                errors=ser.errors       # 如果想让publish字段显示出版社的名字
    # publish = serializers.CharField(source='publish.name')
     # authors = serializers.SerializerMethodField()
    # def get_authors(self, obj):
     # author_list = obj.authors.all()
     # author_ser = AuthorSer(instance=author_list, many=True)
    # return author_ser.data

Django自带序列化组件

serializers(把对象序列化成json字符串)

from django.core import serializers
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部分

from django.db import models

# Create your models here.

class Book(models.Model):
title=models.CharField(max_length=32)
price=models.IntegerField()
pub_date=models.DateField()
publish=models.ForeignKey("Publish")
authors=models.ManyToManyField("Author")
def __str__(self):
return self.title class Publish(models.Model):
name=models.CharField(max_length=32)
email=models.EmailField()
def __str__(self):
return self.name class Author(models.Model):
name=models.CharField(max_length=32)
age=models.IntegerField()
def __str__(self):
return self.name

view部分

from rest_framework.views import APIView
from rest_framework.response import Response
from .models import *
from django.shortcuts import HttpResponse
from django.core import serializers from rest_framework import serializers

<... 这一块代码最好新建一个 .py文件放在里面,这样的话看起来就不是那么乱了
class BookSerializers(serializers.Serializer):
title=serializers.CharField(max_length=32)
price=serializers.IntegerField()
pub_date=serializers.DateField()
publish=serializers.CharField(source="publish.name")
#authors=serializers.CharField(source="authors.all")
authors=serializers.SerializerMethodField()
def get_authors(self,obj):
temp=[]
for author in obj.authors.all():
temp.append(author.name)
return temp
  #此处可以继续用author的Serializers,
  # def get_authors(self,obj):
    # ret=obj.authors.all()
    # ss=AuthorSerializer(ret,many=True)
    # return ss.data
...>
class BookViewSet(APIView): def get(self,request,*args,**kwargs):
book_list=Book.objects.all()
# 序列化方式1:
# from django.forms.models import model_to_dict
# import json
# data=[]
# for obj in book_list:
# data.append(model_to_dict(obj))
# print(data)
# return HttpResponse("ok") # 序列化方式2:
# data=serializers.Serialize("json",book_list)
# return HttpResponse(data) # 序列化方式3:
bs=BookSerializers(book_list,many=True) #many=True代表有多条数据,如果只有一条数据,many=False
return Response(bs.data)
     # 序列化方式4:
   # ret=models.Book.objects.all().values('nid','title')
     # dd=list(ret)
# return HttpResponse(json.dumps(dd))

注意:

source 如果是字段,会显示字段,如果是方法,会执行方法,不用加括号(authors=serializers.CharField(source='authors.all'))

如在模型中定义一个方法,直接可以在在source指定执行

class UserInfo(models.Model):
user_type_choices = (
(1,'普通用户'),
(2,'VIP'),
(3,'SVIP'),
)
user_type = models.IntegerField(choices=user_type_choices) username = models.CharField(max_length=32,unique=True)
password = models.CharField(max_length=64) #视图
ret=models.UserInfo.objects.filter(pk=1).first()
aa=ret.get_user_type_display() #serializer
xx=serializers.CharField(source='get_user_type_display')

小结

# 1 变量名和source指定的值不能一样
# 2 source='publish.name'还支持继续 .
# 3 source 还支持方法(没用)
# 4 支持写方法,如下
#方法一定传一个参数,是当前book对象
publish_dic=serializers.SerializerMethodField()
def get_publish_dic(self,obj):
# 猜,这个obj应该是谁,当前book对象
  return {'id':obj.publish.pk,'name':obj.publish.name} 在线格式化json
-https://www.json.cn/

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

生成hypermedialink(极少数)

class BookSerializers(serializers.ModelSerializer):
class Meta:
model = models.Book
fields = "__all__"
# 生成连接,直接查看出版社详情
publish = serializers.HyperlinkedIdentityField(view_name='ttt', lookup_field='publish_id', lookup_url_kwarg='pkk')
authors=serializers.SerializerMethodField()
def get_authors(self,obj):
ret=obj.authors.all()
ss=AuthorSerializer(ret,many=True)
return ss.data
#-------------- res=BookSerializers(ret,many=True,context={'request': request})
#-------------- class Publish(APIView):
def get(self,request,pkk):
print(pkk)
return HttpResponse('ok')
#----路由---
url(r'^publish/(?P<pkk>\d+)$', views.Publish.as_view(),name='ttt'),

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

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)
class BookSerializer1(serializers.Serializer):
title=serializers.CharField(error_messages={'required': '标题不能为空'}) #这种方式要保存,必须重写create方法

通过源码查看留的校验字段的钩子函数

#is_valid---->self.run_validation-(执行Serializer的run_validation)-->self.to_internal_value(data)---(执行Serializer的run_validation:485行)
def validate_title(self, value):
from rest_framework import exceptions
raise exceptions.ValidationError('看你不顺眼')
return value #全局
def validate(self, attrs):
from rest_framework import exceptions
if attrs.get('title')== attrs.get('title2'):
return attrs
else:
raise exceptions.ValidationError('不想等啊')

序列化组件源码分析

序列化组件,先调用__new__方法,如果many=True,生成ListSerializer对象,如果为False,生成Serializer对象
序列化对象.data方法--调用父类data方法---调用对象自己的to_representation(自定义的序列化类无此方法,去父类找)
Aerializer类里有to_representation方法,for循环执行attribute = field.get_attribute(instance)
再去Field类里去找get_attribute方法,self.source_attrs就是被切分的source,然后执行get_attribute方法,source_attrs
当参数传过去,判断是方法就加括号执行,是属性就把值取出来

图书的增删查改resful接口与上面知识点的实例

视图层

from django.shortcuts import render, HttpResponse
from django.http import JsonResponse
# Create your views here.
from django.views import View class Test(View):
def dispatch(self, request, *args, **kwargs):
# 写代码
obj = super().dispatch(request, *args, **kwargs)
# 写代码
return obj def get(self, request, *args, **kwargs):
return HttpResponse('cbv_get') def post(self, request, *args, **kwargs):
return HttpResponse('cbv_post') user_list = [{'id': 1, 'name': 'lqz', 'age': 18}, {'id': 2, 'name': 'egon', 'age': 17},
{'id': 3, 'name': 'xiaohou', 'age': 16}] def users(request):
response = {'status': 100, 'errors': None}
if request.method == 'GET':
response['users'] = user_list
return JsonResponse(response, safe=False)
if request.method == 'POST':
name = request.POST.get('name')
age = request.POST.get('age')
user_list.append({'id': len(user_list) + 1, 'name': name, 'age': age})
# response['user'] = {'id':len(user_list),'name': name, 'age': age}
response['msg'] = '新增成功'
return JsonResponse(response) def user(request, id):
response = {'status': 100, 'errors': None}
if request.method == 'GET':
id = int(id)
response['user'] = user_list[id]
return JsonResponse(response) from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.request import Request # 基于drf写接口,写cbv
class DrfTest(APIView): def get(self, request, *args, **kwargs):
# request是封装之后的request了,原来的request是request._request
print(type(request._request))
print(type(request))
# 问:当前request对象并没有这些属性,但是能打印出来,为什么?
# 修改了getattr
print(request.method)
print(request.POST)
print(request.GET)
# 就相当于:
print(request.query_params)
print(request._request.GET)
response = {'status': 100, 'errors': None}
response['users'] = user_list
# 用drf的Response,可以通过请求客户端来判断返回数据格式是什么样的
return Response(response)
# return JsonResponse(response) def post(self, request, *args, **kwargs):
# post 提交的数据,urlencode,formdate,json格式,都能从data中取出来
name = request.data.get('name')
# request.FILES
print(name)
return HttpResponse('ok') from app01 import models
from app01.MySer import BookSerializer class Auth():
def authenticate(self,request):
pass # 写一个获取所有图书的接口
class Books(APIView):
authentication_classes=[Auth,]
def get(self, request, *args, **kwargs): response = {'status': 100, 'msg': '成功'}
book_list = models.Book.objects.all()
# 第一个参数是要序列化的queryset对象,如果序列化多条,必须指定many=True
# 问?什么情况下many=False,instance=单个对象的时候
book_ser = BookSerializer(book_list, many=True)
print(book_ser.data)
response['books'] = book_ser.data
return Response(response) def post(self, request):
response = {'status': 100, 'msg': '成功'}
# 提交的字典
# book = request.data
# 传统方法,创建对象保存
# 新方法,通过序列化组件保存,必须用继承自ModelSerializer
# data注意是data
book_ser = BookSerializer(data=request.data)
# is_valid提交的字段校验通过
if book_ser.is_valid():
book_ser.save()
response['book'] = book_ser.data
else:
response['msg'] = book_ser.errors
# return Response(book_ser.data)
return Response(response) class Book(APIView): def get(self, request, id):
response = {'status': 100, 'msg': '成功'}
book = models.Book.objects.filter(pk=id).first()
book_ser = BookSerializer(book, many=False)
response['book'] = book_ser.data
return Response(response) def put(self, request, id):
response = {'status': 100, 'msg': '成功'}
book = models.Book.objects.filter(pk=id).first()
# 修改的话,要把book对象传过来
book_ser = BookSerializer(data=request.data, instance=book)
# is_valid提交的字段校验通过
if book_ser.is_valid():
# save既可以修改,又可以更新
book_ser.save()
response['book'] = book_ser.data
else:
response['msg'] = book_ser.errors
# return Response(book_ser.data)
return Response(response) def delete(self,request,id):
response = {'status': 100, 'msg': '删除成功'}
book = models.Book.objects.filter(pk=id).delete()
return Response(response)

模板层

from django.db import models

# Create your models here.
from django.db import models # Create your models here. class Book(models.Model):
title = models.CharField(max_length=32)
price = models.IntegerField()
pub_date = models.DateField()
publish = models.ForeignKey("Publish")
authors = models.ManyToManyField("Author") def test(self):
return self.title + str(self.price) def __str__(self):
return self.title class Publish(models.Model):
name = models.CharField(max_length=32)
email = models.EmailField() # def __str__(self):
# return self.name
# return str(self.pk) class Author(models.Model):
name = models.CharField(max_length=32)
age = models.IntegerField()
#
# def __str__(self):
# return self.name

自己手动创建的序列化组件层

from rest_framework import serializers

# from rest_framework.request import Request

class AuthorSer(serializers.Serializer):
id = serializers.CharField()
name = serializers.CharField()
age = serializers.CharField() # class BookSerializer(serializers.Serializer):
# id = serializers.CharField()
# # 通过source可以改名
# name = serializers.CharField(source='title')
# price = serializers.CharField()
#
# xxx = serializers.CharField(source='test')
# # 1 变量名和source指定的值不能一样
# # 2 source='publish.name'还支持继续 .
# # 3 source 还支持方法(没用)
# # publish_name = serializers.CharField(source='publish.name')
# # publish_id = serializers.CharField(source='publish.pk')
# # 4 支持写方法,如下
# #方法一定传一个参数,是当前book对象
# publish_dic=serializers.SerializerMethodField()
# def get_publish_dic(self,obj):
# # 猜,这个obj应该是谁,当前book对象
# return {'id':obj.publish.pk,'name':obj.publish.name}
# authors=serializers.SerializerMethodField()
# # def get_authors(self,obj):
# # # 所有作者queryset对象
# # author_list=obj.authors.all()
# # ll=[ {'name':author.name,'id':author.pk} for author in author_list]
# # return ll
# def get_authors(self,obj):
# # 所有作者queryset对象
# author_list=obj.authors.all()
# author_ser=AuthorSer(instance=author_list,many=True)
# return author_ser.data
# ModelSerializer跟表模型绑定的序列化
from app01 import models class BookSerializer(serializers.ModelSerializer):
class Meta:
# 指定表模型
model = models.Book
# 序列化所有字段
fields = '__all__'
# 只想序列化title和id这俩字段
# fields = ['title', 'id']
# exclude 和fields 不要连用
# exclude = ['title']
# 深度,表示连表的深度
# 不建议使用:下几层要取得参数不能控制,官方建议不要超过10,我给你的建议不要超过3
# depth=1
# 全取出来之后,可以在后面覆盖之前的值
# 如果想让publish字段显示出版社的名字
# publish = serializers.CharField(source='publish.name')
# authors = serializers.SerializerMethodField()
# def get_authors(self, obj):
# author_list = obj.authors.all()
# author_ser = AuthorSer(instance=author_list, many=True)
# return author_ser.data title = serializers.CharField(max_length=6, min_length=3, error_messages={'max_length': '太长了'}) # 也有局部钩子和全局钩子
def validate_title(self, value):
from rest_framework import exceptions
print(value)
if value.startswith('sb'):
raise exceptions.ValidationError('不能以sb开头')
return value
# def validate_title(self, value):
# from rest_framework import exceptions
# raise exceptions.ValidationError('看你不顺眼')
# return value

路由

from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^users/', views.DrfTest.as_view()),
# 在这写的实际上就是as_view()内view的内存地址
url(r'^books/', views.Books.as_view()),
url(r'^book/(?P<id>\d+)', views.Book.as_view()),
]

  

Restful framework【第三篇】序列化组件的更多相关文章

  1. Restful Framework (三)

    目录 一.版本 二.解析器 三.序列化 四.请求数据验证 一.版本 回到顶部 程序也来越大时,可能通过版本不同做不同的处理 没用rest_framework之前,我们可以通过以下这样的方式去获取. c ...

  2. Entity Framework 第三篇 实体特性声明

    Entity Framework中对实体的特性声明有着严格的要求 1.实体必须要有主键特性,但是如果实体没有主键特性那怎么办? public int ExecuteSqlCommand(string ...

  3. Restful framework【第二篇】APIView

    安装djangorestframework 方式一:pip3 install djangorestframework 方式二:pycharm图形化界面安装 方式三:pycharm命令行下安装(装在当前 ...

  4. Restful framework【第一篇】RESTful 规范

    什么是RESTful REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为“表征状态转移” REST从资源的角度类审 ...

  5. Restful framework【第九篇】分页器

    基本使用 分页 -简单分页 page_size = api_settings.PAGE_SIZE :每页显示条数 page_query_param = 'page' :查询的页码数 page_size ...

  6. rest_framework序列化组件

    一.Django自带的序列化组件  ==>对象序列化成json格式的字符串 from django.core import serializers from django.core import ...

  7. Django day26 HyperlinkedIdentityField,序列化组件的数据校验以及功能的(全局,局部)钩子函数,序列化组件的反序列化和保存

    一:HyperlinkedIdentityField(用的很少):传三个参数:第一个路由名字,用来反向解析,第二个参数是要反向解析的参数值,第三个参数:有名分组的名字 -1 publish = ser ...

  8. Django高级篇三。restful的解析器,认证组件,权限组件

    一.rest=framework之解析器 1)解析器作用. 根据提交的数据.只解析某些特定的数据.非法数据不接收,为了系统安全问题 比如解析的数据格式有 有application/json,x-www ...

  9. restful framework之序列化组件

    一.Django自带序列化组件 from django.core import serializers def test(request): book_list = Book.objects.all( ...

随机推荐

  1. Python学习笔记之装饰器原理

    def decorator(fn): def wrapper(): print("询价") fn() print("购买成功!") return wrapper ...

  2. JavaScript 创建和浅析自定义对象

    在Js中,除了Array.Date.Number等内置对象外,开发者可以通过Js代码创建自己的对象. 目录 1. 对象特性:描述对象的特性 2. 创建对象方式:对象直接量.new 构造函数.Objec ...

  3. caffe的运行create_data.sh前对VOC2007图片格式的更改

    运用caffe进行深度学习之前需要对图片进行预处理,将图片的大小,格式等进行修改 将300*300的图片改为256*256格式 则将以下参数改为: min_dim=256 max_dim=256 wi ...

  4. hdu5439 二分

    题意 初始给了 1 2 两个数 第二步 因为第2个数是2 所以  在序列后面放上2个2 包括他自己之前有的 序列变成 1 2 2 第三步 因为第3个数是2 所以  在序列后面放上2个3 就变成了 1 ...

  5. jQuery筛选--find(expr|obj|ele)和siblings([expr])

    find(expr|obj|ele) 概述 搜索所有与指定表达式匹配的元素.这个函数是找出正在处理的元素的后代元素的好方法 参数 expr  用于查找的表达式 jQuery object   一个用于 ...

  6. 【2017-2-24】C#循环嵌套,跳转语句,迭代穷举,异常语句,while循环

    循环嵌套 在一个循环体语句中包含另一个循环语句: 99乘法表 ; i <= ; i++) { ; j <= i; j++) { Console.Write(i+"x"+ ...

  7. 特征点方法 - Harris和SURF的手工实现

    整理去年做的小项目,纪念我的图像处理入门. 因为要在DSP上实现,所以完全手工C代码垒起来的,还要保证和PC端跑的结果一样,觉得可能特殊场景会有用,上传github,没有依赖任何库: 格式注释什么的暂 ...

  8. Python 构造一个可接受任意数量参数的函数

    为了能让一个函数接受任意数量的位置参数,可以使用一个* 参数 在这个例子中,rest 是由所有其他位置参数组成的元组.然后我们在代码中把它当成了一个序列来进行后续的计算

  9. 【转】ETL讲解(很详细!!!)

    ETL是将业务系统的数据经过抽取.清洗转换之后加载到数据仓库的过程,目的是将企业中的分散.零乱.标准不统一的数据整合到一起,为企业的决策提供分析依据. ETL是BI项目重要的一个环节. 通常情况下,在 ...

  10. 初探AngularJs框架(一)

    一.需要准备的环境 Nodejs:https://nodejs.org/en/download/ Python:https://www.python.org/downloads/release/pyt ...