序列化

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

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

  1. class Book(models.Model):
  2. title=models.CharField(max_length=32)
  3. price=models.IntegerField()
  4. pub_date=models.DateField()
  5. publish=models.ForeignKey(to="Publish")
  6. authors=models.ManyToManyField(to="Author")
  7.  
  8. def __str__(self):
  9. return self.title
  10.  
  11. class Publish(models.Model):
  12. name=models.CharField(max_length=32)
  13. email=models.EmailField()
  14.  
  15. def __str__(self):
  16. return self.name
  17.  
  18. class Author(models.Model):
  19. name=models.CharField(max_length=32)
  20. age=models.IntegerField()
  21.  
  22. def __str__(self):
  23. return self.name
  24.  
  25. class User(models.Model):
  26. user=models.CharField(max_length=32)
  27. pwd=models.CharField(max_length=32)
  28. user_type=models.IntegerField(choices=((1,"普通用户"),(2,"VIP用户"),(3,"SVIP用户")))
  29.  
  30. def __str__(self):
  31. return self.user
  32.  
  33. class UserToken(models.Model):
  34. user=models.OneToOneField(to="User")
  35. token=models.CharField(max_length=128)
  36.  
  37. def __str__(self):
  38. return self.token

models.py

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

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

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

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

视图(views)

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

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

  1. 处理Book表全部信息,查看、添加
  2. class BookViews(APIView):
  3. def get(self,request,*args,**kwargs):
  4. book_list=Book.objects.all()
  5. # querset数据转化为json数据
  6. bs=BookModelSerializer(book_list,many=True) #queryset时,many=True;单个对象时,默认many=False
  7. # bs.data序列化后的数据[{},{}]
  8. return Response(bs.data)
  9.  
  10. def post(self,request,*args,**kwargs):
  11. # 获取前端提交的数据
  12. obj=request.data
  13. #json数据转化为queryset数据
  14. bs=BookModelSerializer(data=obj)
  15. # 验证
  16. if bs.is_valid():
  17. bs.save()
  18. # 显示json数据
  19. return Response(bs.data)
  20. else:
  21. # 显示错误信息
  22. return Response(bs.errors)
  23.  
  24. # 处理指定book的信息,查看、编辑、删除
  25. class BookDetailViews(APIView):
  26.  
  27. def get(self,request,pk,*rags,**kwargs):
  28. book_obj=Book.objects.filter(pk=pk).first()
  29. if not book_obj:
  30. return Response("没有这条记录")
  31. bs=BookModelSerializer(book_obj)
  32. return Response(bs.data)
  33.  
  34. def put(self,request,pk,*rags,**kwargs):
  35. # 获取编辑后的json数据
  36. obj=request.data
  37. book_obj=Book.objects.filter(pk=pk).first()
  38. # 将data的json数据转换为queryset(book_obj)数据
  39. bs=BookModelSerializer(data=obj,instance=book_obj)
  40. if bs.is_valid():
  41. bs.save()
  42. return Response(bs.data)
  43. else:
  44. return Response(bs.errors)
  45.  
  46. def delete(self,request,pk,*args,**kwargs):
  47. Book.objects.filter(pk=pk).delete()
  48. return Response("删除成功")

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

  1. from rest_framework import mixins
  2. from rest_framework import generics
  3.  
  4. class BookViews(mixins.ListModelMixin,
  5. mixins.CreateModelMixin,
  6. generics.GenericAPIView):
  7.  
  8. queryset = Book.objects.all()
  9. serializer_class = BookModelSerializer
  10. # 继承mixins.ListModelMixin
  11. def get(self,request,*args,**kwargs):
  12. return self.list(request, *args, **kwargs)
  13.  
  14. # 继承mixins.CreateModelMixin
  15. def post(self,request,*args,**kwargs):
  16. return self.create(request,*args,**kwargs)
  17.  
  18. class BookDetailViews(mixins.RetrieveModelMixin,
  19. mixins.UpdateModelMixin,
  20. mixins.DestroyModelMixin,
  21. generics.GenericAPIView):
  22. # lookup_field = 'pk' 找到url(r'^books/(?P<pk>\d+)/$', views.BookDetailViews.as_view())generics.GenericAPIView中默认设置好了,先queryset查询再进行过滤
  23. queryset = Book.objects.all()
  24. serializer_class = BookModelSerializer
  25.  
  26. def get(self,request,*args,**kwargs):
  27. return self.retrieve( request, *args, **kwargs)
  28.  
  29. def put(self,request,*args,**kwargs):
  30. return self.update(request,*args,**kwargs)
  31.  
  32. def delete(self,request,*args,**kwargs):
  33. return self.destroy(request,*args,**kwargs)

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

  1. from rest_framework import generics
  1. ListCreateAPIView继承mixins.ListModelMixin,mixins.CreateModelMixin,GenericAPIView
  2.  
  3. class BookViews(generics.ListCreateAPIView):
  4. queryset = Book.objects.all()
  5. serializer_class = BookModelSerializer
  6.  
  7. class BookDetailViews(generics.RetrieveUpdateDestroyAPIView):
  8. queryset = Book.objects.all()
  9. serializer_class = BookModelSerializer

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

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

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

解释器(parser)

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

  1. urlencoded 对应 格式一:name=alex&age=123&email=131232 json 对应 格式二:{name:'xx',age:'xxx'}
  1. 1Django中的request类:
  1.   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中有元数据
  1. 2rest_frmaework中的request类:
  1.   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

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

全局使用parser:

settings.py

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

分页(page)

一、自定义页码分页

1.自定义list()分页

view.py

  1. from rest_framework.pagination import PageNumberPagination
  2. class BookViewsSet(viewsets.ModelViewSet): #重新定义了as_view()
  3.  
  4. queryset = Book.objects.all()
  5. serializer_class = BookModelSerializer
  6.  
  7. #自定义list ,分页
  8. def list(self,request,*args,**kwargs):
  9. book_list=Book.objects.all()
  10. print(book_list)
  11. pnp=PageNumberPagination()
  12. pager_book=pnp.paginate_queryset(queryset=book_list,request=request,view=self)
  13. print("pager_book",pager_book)
  14. # 序列化分页后的数据
  15. bs=BookModelSerializer(pager_book,many=True)
  16. return pnp.get_paginated_response(bs.data)

settings.py

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

2.自定义页码分页

pageing.py

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

views.py

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

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

pageing.py

  1. from rest_framework.pagination import PageNumberPagination,LimitOffsetPagination
  2.  
  3. #用法http://127.0.0.1:8001/books/?offset=1&limit=2 根据起始索引和每页显示的个数
  4. class PageBook(LimitOffsetPagination):
  5. # 默认每页显示的数据条数
  6. default_limit = 2
  7. # URL中传入的显示数据条数的参数
  8. limit_query_param = 'limit'
  9. # URL中传入的数据位置的参数
  10. offset_query_param = 'offset'
  11. # 最大每页显得条数
  12. max_limit = None

views.py

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

三、游标分页

pageing.py

  1. # 游标分页 对cursor进行加密,只能通过指定的url进行访问(只能通过图片中的url访问)
  2.  
  3. class PageBook(CursorPagination):
  4. # URL传入的游标参数
  5. cursor_query_param = 'page'
  6. # 默认每页显示的数据条数
  7. page_size = 2
  8. # URL传入的每页显示条数的参数
  9. page_size_query_param = 'page_size'
  10. # 每页显示数据最大条数
  11. max_page_size = 1000
  12.  
  13. # 根据ID从大到小排列
  14. ordering = "id"

views.py

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

路由系统

1.自定义路由

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

2.自动生成url

  1. # 自动生成url
  2. from django.conf.urls import url,include
  3. from api import views
  4. from rest_framework import routers
  5.  
  6. router = routers.DefaultRouter()
  7. router.register(r'books', views.BookViewsSet)
  8.  
  9. urlpatterns = [
  10.  
  11. # 自动生成url
  12. url(r'^',include(router.urls)),
  13. ]

响应器

根据 用户请求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

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

以下访问urls.py都一样

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

1. 访问json

urls.py:

  1.   http://127.0.0.1:8000/books/?format=json
  2.  
  3.   http://127.0.0.1:8000/books.json
  4.  
  5.   http://127.0.0.1:8000/books

views.py

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

2.表格

urls.py:

  1.   http://127.0.0.1:8000/books/?format=admin
  2.  
  3.   http://127.0.0.1:8000/books.admin
  4.  
  5.   http://127.0.0.1:8000/books

views.py

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

3.form表单

urls.py:

  1.   http://127.0.0.1:8000/books/?format=form
  2.  
  3.   http://127.0.0.1:8000/books.form
  4.  
  5.   http://127.0.0.1:8000/books

views.py

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

4.自定义显示模板

urls.py:

  1.   http://127.0.0.1:8000/books/?format=html
  2.  
  3.   http://127.0.0.1:8000/books.html
  4.  
  5.   http://127.0.0.1:8000/books

views.py

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

books.html

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

3.form表单

urls.py:

  1.   http://127.0.0.1:8000/books/?format=api
  2.  
  3.   http://127.0.0.1:8000/books.api
  4.  
  5.   http://127.0.0.1:8000/books

views.py

  1. class BookViewsSet(viewsets.ModelViewSet):
    # 响应器
    renderer_classes=[renderer_classes=[HTMLFormRenderer]]
  1. 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. Elasticsearch 监控和部署

    Elasticsearch: ! [ https://elasticsearch.cn/book/elasticsearch_definitive_guide_2.x/_cluster_health. ...

  2. 弹框中的elment-form在弹框重新打开后,怎么初始化验证信息

    如果弹框关闭前有错误提示,弹框重新打开,由于没重新刷新页面,该错误还是存在.... 解决办法:弹框中的内容写成一个组件,prop接收父元素弹框的状态,并监听且reset表格 1. cnpm insta ...

  3. [poj] 2396 [zoj] 1994 budget || 有源汇的上下界可行流

    poj原题 zoj原题 //注意zoj最后一行不要多输出空行 现在要针对多赛区竞赛制定一个预算,该预算是一个行代表不同种类支出.列代表不同赛区支出的矩阵.组委会曾经开会讨论过各类支出的总和,以及各赛区 ...

  4. [学习笔记]最小割之最小点权覆盖&&最大点权独立集

    最小点权覆盖 给出一个二分图,每个点有一个非负点权 要求选出一些点构成一个覆盖,问点权最小是多少 建模: S到左部点,容量为点权 右部点到T,容量为点权 左部点到右部点的边,容量inf 求最小割即可. ...

  5. 【BZOJ 1082】[SCOI2005]栅栏 二分+dfs

    对于最优解我们发现所有的最优解都可以是前多少多少个,那么我们就二分这个前多少多少个,然后用dfs去判解,我们发现在dfs的过程中如果不剪枝几乎必T,所以我们就需要一些有效的剪枝 I. 我们在枚举过程中 ...

  6. Codeforces Round #515 (Div. 3) E. Binary Numbers AND Sum

    E. Binary Numbers AND Sum 题目链接:https://codeforces.com/contest/1066/problem/E 题意: 给出两个用二进制表示的数,然后将第二个 ...

  7. CentOS 安装 debuginfo-install

    安装debuginfo相关的包步骤如下: 1. 修改文件/etc/yum.repos.d/CentOS-Debuginfo.repo中的enabled参数,将其值修改为1 2. 使用命令: yum i ...

  8. itext转html为pdf遇到的问题

    记录一下使用itext将html文件转为pdf文件遇到的一些问题 1.中文不显示 原因:itext默认不支持中文 解决方法:引入中文字体 需要注意的是在java代码中设置好中文字体后,还需要在html ...

  9. Spring学习-- Bean 的作用域

    Bean 的作用域: 在 Spring 中 , 可以在 <bean> 元素的 scope 属性里设置 bean 的作用域. 默认情况下 , Spring 只为每个在 IOC 容器里声明的 ...

  10. nodejs与sqlite

    //打开数据库var db = new sqlite3.Database('xx.db'); // 关闭数据库db.close(); db.run('xx');  // 数据库对象的run函数可以执行 ...