序列化

序列化:转化数据和校验数据(提交数据时校验数据类型)

开发我们的Web API的第一件事是为我们的Web API提供一种将代码片段实例序列化和反序列化为诸如json之类的表示形式的方式。我们可以通过声明与Django forms非常相似的序列化器(serializers)来实现。

class Book(models.Model):
title=models.CharField(max_length=32)
price=models.IntegerField()
pub_date=models.DateField()
publish=models.ForeignKey(to="Publish")
authors=models.ManyToManyField(to="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 class User(models.Model):
user=models.CharField(max_length=32)
pwd=models.CharField(max_length=32)
user_type=models.IntegerField(choices=((1,"普通用户"),(2,"VIP用户"),(3,"SVIP用户"))) def __str__(self):
return self.user class UserToken(models.Model):
user=models.OneToOneField(to="User")
token=models.CharField(max_length=128) def __str__(self):
return self.token

models.py

1.使用serializers(用法类似与form组件)

from rest_framework import serializers
#为Book表定制序列化组件
#使用Serializer
class BookSerializers(serializers.Serializer):
  #普通字段
title=serializers.CharField(max_length=32)
price=serializers.IntegerField()
pub_date=serializers.DateField()
# 一对多使用Charfiled类型,source更改显示的字段
publish=serializers.CharField(source="publish.email")
# 多对多字段
authors=serializers.SerializerMethodField()
def get_authors(self,obj):#obj为book对象
temp=[]
for author in obj.authors.all():
temp.append({"id":author.id,"name":author.name})
return temp

2.使用ModelSerializer(使用方法类似与modelform组件)

class BookModelSerializer(serializers.ModelSerializer):
class Meta:
model=Book
fields="__all__"
# exclude=["authors",] #显示authors以外的字段(单独使用) # authors=serializers.SerializerMethodField() #可以和fields=“__all__”配合使用
# def get_authors(self,obj):
# temp=[]
# for author in obj.authors.all():
# temp.append({"id":author.id,"name":author.name})
# return temp

视图(views)

class BookViews(APIView):
pass
class BookViews(其他类):
  queryset=Book.objects.all() #必须写queryset,不写有可能报错(源码断言处理)
断言:
assert self.queryset is not None, (
"'%s' should either include a `queryset` attribute, "
"or override the `get_queryset()` method."
% self.__class__.__name__
)

1.继承APIView类(继承了View)

处理Book表全部信息,查看、添加
class BookViews(APIView):
def get(self,request,*args,**kwargs):
book_list=Book.objects.all()
# querset数据转化为json数据
bs=BookModelSerializer(book_list,many=True) #queryset时,many=True;单个对象时,默认many=False
# bs.data序列化后的数据[{},{}]
return Response(bs.data) def post(self,request,*args,**kwargs):
# 获取前端提交的数据
obj=request.data
#json数据转化为queryset数据
bs=BookModelSerializer(data=obj)
# 验证
if bs.is_valid():
bs.save()
# 显示json数据
return Response(bs.data)
else:
# 显示错误信息
return Response(bs.errors) # 处理指定book的信息,查看、编辑、删除
class BookDetailViews(APIView): def get(self,request,pk,*rags,**kwargs):
book_obj=Book.objects.filter(pk=pk).first()
if not book_obj:
return Response("没有这条记录")
bs=BookModelSerializer(book_obj)
return Response(bs.data) def put(self,request,pk,*rags,**kwargs):
# 获取编辑后的json数据
obj=request.data
book_obj=Book.objects.filter(pk=pk).first()
# 将data的json数据转换为queryset(book_obj)数据
bs=BookModelSerializer(data=obj,instance=book_obj)
if bs.is_valid():
bs.save()
return Response(bs.data)
else:
return Response(bs.errors) def delete(self,request,pk,*args,**kwargs):
Book.objects.filter(pk=pk).delete()
return Response("删除成功")

2.使用Mixin类(ListModelMixin等中实现了增删改查方法)

from rest_framework import mixins
from rest_framework import generics class BookViews(mixins.ListModelMixin,
mixins.CreateModelMixin,
generics.GenericAPIView): queryset = Book.objects.all()
serializer_class = BookModelSerializer
# 继承mixins.ListModelMixin
def get(self,request,*args,**kwargs):
return self.list(request, *args, **kwargs) # 继承mixins.CreateModelMixin
def post(self,request,*args,**kwargs):
return self.create(request,*args,**kwargs) class BookDetailViews(mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
generics.GenericAPIView):
# lookup_field = 'pk' 找到url(r'^books/(?P<pk>\d+)/$', views.BookDetailViews.as_view())generics.GenericAPIView中默认设置好了,先queryset查询再进行过滤
queryset = Book.objects.all()
serializer_class = BookModelSerializer def get(self,request,*args,**kwargs):
return self.retrieve( request, *args, **kwargs) def put(self,request,*args,**kwargs):
return self.update(request,*args,**kwargs) def delete(self,request,*args,**kwargs):
return self.destroy(request,*args,**kwargs)

3.使用通用的基于类视图

from rest_framework import generics
ListCreateAPIView继承mixins.ListModelMixin,mixins.CreateModelMixin,GenericAPIView

class BookViews(generics.ListCreateAPIView):
queryset = Book.objects.all()
serializer_class = BookModelSerializer class BookDetailViews(generics.RetrieveUpdateDestroyAPIView):
queryset = Book.objects.all()
serializer_class = BookModelSerializer

4.终极版viewsets.ModelViewSet(重新定义了as_view())

###############终极版viewsets.ModelViewSet###########

from rest_framework import viewsetsclass BookViewsSet(viewsets.ModelViewSet):
queryset = Book.objects.all()
serializer_class = BookModelSerializer urls.py
  url(r'^books/$',views.BookViewsSet.as_view({"get":"list","post":"create"})),
  url(r'^books/(?P<pk>\d+)/$',views.BookViewsSet.as_view({"get":"retrieve","put":"update","delete":"destr

ModelViewSet类的继承关系(自己有的用自己的,自己没有的用父类的)

解释器(parser)

根据请求头content_type对应的的解析器类型进行请求体处理

urlencoded 对应 格式一:name=alex&age=123&email=131232         json 对应 格式二:{name:'xx',age:'xxx'}
1、Django中的request类:
  from django.core.handlers.wsgi import WSGIRequest
  只是对 "multipart/form-data"(上传文件)和"application/x-www-form-urlencoded"(如form表单)进行了处理,其他类型的请求头,都要进行解码和反序列化(json.loads.(request.body.decode="utf8"))
  只有在content_type="multipart/form-data"或"application/x-www-form-urlencoded"时,request.POST中才有数据request.body中有元数据
2、rest_frmaework中的request类:
  from rest_framework.parsers import JSONParser,FileUploadParser,FormParser,MultiPartParser
  rest_frmaework:中将解析器的种类扩大有 JSONParser,FileUploadParser,FormParser,MultiPartParser所有数据都在request.data中
  个别特殊的值可以通过request._request 来进行获取 因为它对Django中的request进行了二次封装

    第一次:
        头:
          content-type: application/x-www-form-urlencoded
        体:
          k1=v1&k2=v2
        request.data 接收到的是QueryDict类型

    第二次:
        头:
          content-type: application/json
        体:
          {"k1":"v1","k2":"v2"}

        reuqest.data 接收到的是dict类型

在rest_frmaework中:

局部使用parser:

views.py

from rest_framework.parsers import JSONParser,FormParser,FileUploadParser,MultiPartParser 默认使用JSONParser,FormParser
class BookViewsSet(viewsets.ModelViewSet): #重新定义了as_view()
# 解析器
parser_classes=[JSONParser,FileUploadParser,FormParser,MultiPartParser] queryset = Book.objects.all()
serializer_class = BookModelSerializer

全局使用parser:

settings.py

REST_FRAMEWORK={# 解析器
"DEFAULT_PARSER_CLASSES":["rest_framework.parsers.JSONParser","rest_framework.parsers.FileUploadParser",] }

分页(page)

一、自定义页码分页

1.自定义list()分页

view.py

from rest_framework.pagination import PageNumberPagination
class BookViewsSet(viewsets.ModelViewSet): #重新定义了as_view() queryset = Book.objects.all()
serializer_class = BookModelSerializer #自定义list ,分页
def list(self,request,*args,**kwargs):
book_list=Book.objects.all()
print(book_list)
pnp=PageNumberPagination()
pager_book=pnp.paginate_queryset(queryset=book_list,request=request,view=self)
print("pager_book",pager_book)
# 序列化分页后的数据
bs=BookModelSerializer(pager_book,many=True)
return pnp.get_paginated_response(bs.data)

settings.py

REST_FRAMEWORK={
# 自定义list()分页,每页显示的个数
"PAGE_SIZE": 2
}

2.自定义页码分页

pageing.py

from rest_framework.pagination import PageNumberPagination
class PageBook(PageNumberPagination):
page_size = 1
page_query_param = 'page'
page_size_query_param = "size"
max_page_size =1

views.py

class BookViewsSet(viewsets.ModelViewSet): #重新定义了as_view()
# 分页
pagination_class=PageBook queryset = Book.objects.all()
serializer_class = BookModelSerializer

二、按照索引和每页显示的个数

pageing.py

from rest_framework.pagination import PageNumberPagination,LimitOffsetPagination

#用法http://127.0.0.1:8001/books/?offset=1&limit=2   根据起始索引和每页显示的个数
class PageBook(LimitOffsetPagination):
# 默认每页显示的数据条数
default_limit = 2
# URL中传入的显示数据条数的参数
limit_query_param = 'limit'
# URL中传入的数据位置的参数
offset_query_param = 'offset'
# 最大每页显得条数
max_limit = None

views.py

class BookViewsSet(viewsets.ModelViewSet): #重新定义了as_view()
# 分页
pagination_class=PageBook queryset = Book.objects.all()
serializer_class = BookModelSerializer

三、游标分页

pageing.py

# 游标分页  对cursor进行加密,只能通过指定的url进行访问(只能通过图片中的url访问)

class PageBook(CursorPagination):
# URL传入的游标参数
cursor_query_param = 'page'
# 默认每页显示的数据条数
page_size = 2
# URL传入的每页显示条数的参数
page_size_query_param = 'page_size'
# 每页显示数据最大条数
max_page_size = 1000 # 根据ID从大到小排列
ordering = "id"

views.py

class BookViewsSet(viewsets.ModelViewSet): #重新定义了as_view()
# 分页
pagination_class=PageBook queryset = Book.objects.all()
serializer_class = BookModelSerializer

路由系统

1.自定义路由

  http://127.0.0.1:8001/books/?format=json   浏览器中可以直接访问json数据
  url(r'^books/$',views.BookViewsSet.as_view({"get":"list","post":"create"})),

  #http://127.0.0.1:8001/books.json  或  http://127.0.0.1:8001/books/?format=json   浏览器中可以直接访问json数据
url(r'^books\.(?P<format>[a-z0-9]+)$',views.BookViewsSet.as_view({"get":"list","post":"create"})),

2.自动生成url

# 自动生成url
from django.conf.urls import url,include
from api import views
from rest_framework import routers router = routers.DefaultRouter()
router.register(r'books', views.BookViewsSet) urlpatterns = [ # 自动生成url
url(r'^',include(router.urls)),
]

响应器

根据 用户请求URL 或 用户可接受的类型,筛选出合适的 渲染组件。
用户请求URL:

  http://127.0.0.1:8000/books/?format=json

  http://127.0.0.1:8000/books.json

  http://127.0.0.1:8000/books

用户请求头:

  Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8

from rest_framework.renderers import BrowsableAPIRenderer,JSONRenderer,AdminRenderer,HTMLFormRenderer,TemplateHTMLRenderer

以下访问urls.py都一样

urlpatterns = [
url(
# http://127.0.0.1:8001/books/?format=json或http://127.0.0.1:8001/books.json #浏览器中可以直接访问json数据
url(r'^books\.(?P<format>[a-z0-9]+)$',views.BookViewsSet.as_view({"get":"list","post":"create"})),
]

1. 访问json

urls.py:

  http://127.0.0.1:8000/books/?format=json

  http://127.0.0.1:8000/books.json

  http://127.0.0.1:8000/books

views.py

class BookViewsSet(viewsets.ModelViewSet): 
# 响应器
renderer_classes=[JSONRenderer]
    queryset = Book.objects.all()
serializer_class = BookModelSerializer

2.表格

urls.py:

  http://127.0.0.1:8000/books/?format=admin

  http://127.0.0.1:8000/books.admin

  http://127.0.0.1:8000/books

views.py

class BookViewsSet(viewsets.ModelViewSet): 
# 响应器
renderer_classes=[AdminRenderer]
    queryset = Book.objects.all()
serializer_class = BookModelSerializer

3.form表单

urls.py:

  http://127.0.0.1:8000/books/?format=form

  http://127.0.0.1:8000/books.form

  http://127.0.0.1:8000/books

views.py

class BookViewsSet(viewsets.ModelViewSet): 
# 响应器
renderer_classes=[HTMLFormRenderer]
    queryset = Book.objects.all()
serializer_class = BookModelSerializer

4.自定义显示模板

urls.py:

  http://127.0.0.1:8000/books/?format=html

  http://127.0.0.1:8000/books.html

  http://127.0.0.1:8000/books

views.py

class BookViewsSet(viewsets.ModelViewSet): 
# 响应器
renderer_classes=[TemplateHTMLRenderer,]
  def get(self, request, *args, **kwargs):
book_list = Books.objects.all()
bs = BookSerializer(instance=book_list, many=True)
return Response(bs.data, template_name='books.html')

books.html

 1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8">
5 <title>Title</title>
6 </head>
7 <body>
8 {{ title }}
9 {{ price }}11 </body>
12 </html>

3.form表单

urls.py:

  http://127.0.0.1:8000/books/?format=api

  http://127.0.0.1:8000/books.api

  http://127.0.0.1:8000/books

views.py

class BookViewsSet(viewsets.ModelViewSet): 
# 响应器
renderer_classes=[renderer_classes=[HTMLFormRenderer]]
    queryset = Book.objects.all()
serializer_class = BookModelSerializer

待续

rest_frameword框架的基本组件的更多相关文章

  1. 从零开始,搭建博客系统MVC5+EF6搭建框架(4)上,前后台页面布局页面实现,介绍使用的UI框架以及JS组件

    一.博客系统进度回顾以及页面设计 1.1页面设计说明 紧接前面基础基本完成了框架搭建,现在开始设计页面,前台页面设计我是模仿我博客园的风格来设计的,后台是常规的左右布局风格. 1.2前台页面风格 主页 ...

  2. 实例演示使用RDIFramework.NET 框架的工作流组件进行业务流程的定义—请假申请流程-Web

    实例演示使用RDIFramework.NET 框架的工作流组件 进行业务流程的定义—请假申请流程-Web 参考文章: RDIFramework.NET — 基于.NET的快速信息化系统开发框架 — 系 ...

  3. DRF框架之认证组件用法(第四天)

    1. 什么是drf 框架的认证组件: auth 就等于是jango中的Auth模块,Auth是自带session信息,但是 drf的认证组件可以自定义token携带过去,去判断用的 2.如何实现认证呢 ...

  4. 【干货】利用MVC5+EF6搭建博客系统(四)(上)前后台页面布局页面实现,介绍使用的UI框架以及JS组件

    一.博客系统进度回顾以及页面设计 1.1页面设计说明 紧接前面基础基本完成了框架搭建,现在开始设计页面,前台页面设计我是模仿我博客园的风格来设计的,后台是常规的左右布局风格. 1.2前台页面风格 主页 ...

  5. est-framework框架的基本组件

    rest-framework框架的基本组件   快速实例 Quickstart 序列化 创建一个序列化类 简单使用 开发我们的Web API的第一件事是为我们的Web API提供一种将代码片段实例序列 ...

  6. Vue 框架-09-初识组件的应用

    Vue 框架-09-初识组件的应用 今天的第一个小实例,初步使用组件: 在 app.js 中定义模板组件,在 html 文件中使用自定义标签来显示 js 文件中定义的 html 代码块 比如说,下面定 ...

  7. Django框架 之 form组件的钩子

    Django框架 之 form组件的钩子 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 3 ...

  8. Django框架 之 modelform组件

    Django框架 之 modelform组件 浏览目录 创建mldelform 添加记录 编辑记录 Django框架中的modelform组件 通过名字我们可以看出来,这个组件的功能就是把model和 ...

  9. Django框架 之 form组件

    Django框架 之 form组件 浏览目录 Form介绍 普通的登录 使用form组件 Form详情 常用字段 校验 进阶 使用Django Form流程 一.Form介绍 我们之前在HTML页面中 ...

随机推荐

  1. C语言单元测试

    转自http://blog.csdn.net/colin719/article/details/1420583 对于敏捷开发来说,单元测试必不可少,对于Java开发来说,JUnit非常好,对于C++开 ...

  2. 物联网PPT智能家居王思齐和陈由钧第10组

    ppt做完了但是不知道怎么用博客园发ppt!只能发几个图片了

  3. symfony安装总结

    将D:\ApacheServer\php路径添加到环境变量path中,在cmd命令行中可以执行php命令 打开php.ini 打开extension=php_openssl.dll file_put_ ...

  4. docker/qemu中是如何对设备管理的

    文件系统中包括实际的磁盘中可读可写的. 容器中看到的设备是啥子呢?--docker qemu也是一样,在qemu中添加一个设备的物理意义是啥子嘛 其实设备也没啥好新奇的,不就是一个普通的文件么,然后在 ...

  5. [剑指Offer] 8.跳台阶

     题目描述 一只青蛙一次可以跳上1级台阶,也可以跳上2级.求该青蛙跳上一个n级的台阶总共有多少种跳法. [思路]与斐波那契数列类似 class Solution { public: int jumpF ...

  6. Luogu3731 HAOI2017新型城市化(二分图匹配+强连通分量)

    将未建立贸易关系看成连一条边,那么这显然是个二分图.最大城市群即最大独立集,也即n-最大匹配.现在要求的就是删哪些边会使最大匹配减少,也即求哪些边一定在最大匹配中. 首先范围有点大,当然是跑个dini ...

  7. 如何开始创建第一个基于Spring MVC的Controller

    万事开头难,良好的开端是成功的一半! 以下示例怎么开始创建我们的第一个Spring MVC控制器Controller 1.新建一个java类,命名为:MyFirstController,包含以下代码, ...

  8. Clevo P950系列拆机

    Clevo P950系列(包括神舟精盾T96/T97/T96C/T96E/T97E,炫龙耀9000,铁头人T800同模具机型)拆机 拆机恢复时间:20181203 12:28-14:58   一.普通 ...

  9. tyvj1305 最大子序和(单调队列

    题目地址:http://www.joyoi.cn/problem/tyvj-1305 最大子序和 题目限制 时间限制 内存限制 评测方式 题目来源 1000ms 131072KiB 标准比较器 Loc ...

  10. ShareSDK入门指南:Android 10分钟快速集成

    ShareSDK 官方已提供Android 快速集成教程,以官方教程为参考,本文重点指导大家在集成中遇到的问题. Android 快速集成官方教程:http://wiki.mob.com/Androi ...