一、学习restframework之前准备

1、json格式若想展示中文,需要ensure_ascii=False

  1. import json
  2.  
  3. dic={'name':'你好'}
  4. print(json.dumps(dic,ensure_ascii=False))

2、不基于restframework也可以通过django来做符合restframework的规范接口设计,Jsonresponse,若想在json展示中文,如下

  1. def books(request):
  2.  
  3. ll=[{'name':'python全站开发','price':},{'name':'linux','price':}]
  4.  
  5. # return HttpResponse(json.dumps(ll))
  6. return JsonResponse(ll,safe=False,json_dumps_params={'ensure_ascii':False})

3、原声cbv执行流程

  1. url(r'^books/$', views.Book.as_view()),
  1.  
  2. 原声cbv执行流程---》as_view----》dispatch---》相应到具体的函数
  3. from django.views import View
  4. class Book(View):
  5. def get(self,reuquest):
  6. # reuquest.method
  7. return HttpResponse('get')
  8. def post(self,request):
  9. return HttpResponse('post')

3、分析restframework

  1. restfu(规范)
  2. 是什么:
  3. -面向资源编程
  4. -getBooklist:获取图书列表
  5. -符合规范的:books
  6. 规范:
  7. -methodget----》books----》取到所有的书
  8.  
  9. post———》books---》新增图书
  10.  
  11. put/patch--》books/id---》修改图书
  12.  
  13. delete---》books/id---》删除图书
  14. -https://api.example.com/v1/zoos?limit=10
  15. -
  16.  
  17. drf
  18. 安装(app):pip3 install djangorestframework
  19. -基于drfresful的接口,得写CBV
  20. -request对象,源码分析
  21. -APIView源码分析

二、restframework使用

1、POST没法解析json格式,可以在body里取值出来序列化反序列化操作转成字典,目前drf可以在前台提交post后台取值的话用data,

  1. from rest_framework.views import APIView
  2.  
  3. class Book(APIView):
  4. def get(self,request):
  5. # 拿原来的request对象
  6. # request._request
  7. # print(request.method)
  8. # print(request._request.method)
  9. # request.POST
  10. # request.method
  11. return HttpResponse('get')
  12. def post(self,request):
  13. print(request.method)
  14. print(request._request.method)
  15. print(request.POST)
  16.  
  17. # 用apiview之后,再取数据,从request.data
  18. print(request.data)
  19. return HttpResponse('post')

2、用Postman模拟发http请求,网上直接下载,data可以类似于解析器,解析form-data,urlencoded,json格式,而django只能解析form-data,urlencoded两种格式

三、序列化组件

1、从数据库取出来的都是qs类型,里面套了一个一个对象,要传到前台去必须要json格式,符合drf规范的第一种方式

  1. 数据库配置
    DATABASES = {
  2. 'default': {
  3. 'ENGINE': 'django.db.backends.mysql',
  4. 'NAME': 'resful',
  5. 'USER':'root',
  6. 'PASSWORD':'',
  7. 'HOST':'127.0.0.1',
  8. 'PORT':,
  9. }
  10. }

models取值为qureryset类型,

  1. from app01 import models
  2. 序列化组建
  3. 第一种方式
  4. class Book(APIView):
  5. def get(self,request):
  6. response={'status':,'msg':None}
  7. books=models.Book.objects.all()
  8. # ll=[]
  9. # for book in books:
  10. # ll.append({'name':book.name,''})
  11. ll=[ {'name':book.name,'price':book.price} for book in books]
  12. response['msg']='查询成功'
  13. response['data']=ll
  14. return JsonResponse(response,safe=False)
  15.  
  16. # return HttpResponse('get')
  17. def post(self,request):
  18.  
  19. return HttpResponse('post')

2、第二种方式,用django子自带序列化组件serializers(Django内置的serializers(把对象序列化成json字符串),但是有个缺点不能定制化

  1. from django.core import serializers
  2.  
  3. class Book(APIView):
  4. def get(self,request):
  5. # response={'status':,'msg':None}
  6. books = models.Book.objects.all()
  7. ret = serializers.serialize("json", books)
  8. return HttpResponse(ret)
  9.  
  10. # return HttpResponse('get')
  11. def post(self,request):
  12.  
  13. return HttpResponse('post')

3、用drf自带的组件,建议的话新建个py在APP下,方便解耦,如myserial.py,为符合drf格式,里面新建个response类,见下

  1. - 导入:from rest_framework import serializers
  2. - 写一个类(名字任意),继承serializers.Serializer
  3. class BookSer(serializers.Serializer):
  4. nid=serializers.IntegerField()
  5. name3=serializers.CharField(source='name')
  6. price=serializers.CharField()
  7. # publish_date = serializers.DateField()
  8. publish_date = serializers.CharField()
  9. # publish=serializers.CharField(source='publish.email')
  10. publish=serializers.CharField(source='publish.name')
  11. xxx=serializers.CharField(source='test')
  12. - 如果不指定source,字段名,必须跟数据库列名一致
  13. - source--》既可以指定数据属性,又可以指定方法属性,可以写(publish.name
  14. - 使用:
  15. -查询出要序列化的数据:books = models.Book.objects.all()
  16. -ret=myserial.BookSer(books,many=True)-----》多条(queryset对象),必须指定many=True
  17. -ret=myserial.BookSer(books,many=False)-----》一条(Book对象),必须指定many=False
  18. - aa=serializers.SerializerMethodField()
  19. -必须配套一个方法(get_aa(self,obj)),方法返回结果,会赋给aa
  20. -在方法内部,可以继续用序列化组件

myserial.py

  1. from rest_framework import serializers
  2.  
  3. class BookSer(serializers.Serializer):
  4. nid=serializers.IntegerField()
  5. name3=serializers.CharField(source='name')
  6. price=serializers.CharField()
  7. # publish_date = serializers.DateField()
  8. publish_date = serializers.CharField()
  9. # publish=serializers.CharField(source='publish.email')
  10. publish=serializers.CharField(source='publish.name')
  11. xxx=serializers.CharField(source='test')
  12. # authors=serializers.CharField(source='authors.all')
  13. # SerializerMethodField,可以写一个方法方法名叫:get_字段名字,方法返回值,会赋给authors
  14. aa=serializers.SerializerMethodField()
  15. # def get_authors(self,obj):
  16. # authors=obj.authors.all()
  17. # # ll=[ author.name for author in authors]
  18. # ll=[ {'name':author.name,'age':author.age} for author in authors]
  19. # return ll
  20. def get_aa(self, obj):
  21. authors = obj.authors.all()
  22. # ll=[ author.name for author in authors]
  23. ser=AuthorSer(authors,many=True)
  24. return ser.data

models.py

  1. class Book(models.Model):
  2. nid = models.AutoField(primary_key=True)
  3. name = models.CharField(max_length=)
  4. price = models.DecimalField(max_digits=, decimal_places=)
  5. publish_date = models.DateField(auto_now_add=True)
  6.  
  7. publish = models.ForeignKey(to='Publish',to_field='nid',on_delete=models.CASCADE)
  8. authors=models.ManyToManyField(to='Author')
  9.  
  10. def test(self):
  11. return 'ttttttt'
  12. def __str__(self):
  13. return self.name

使用,为符合drf格式,里面新建个response类,@property让类方法变属性,不需要(),直接点+属性就ok了

  1. class MyResponse():
  2. def __init__(self):
  3. self.status =
  4. self.msg = None
  5.  
  6. @property
  7. def get_dic(self):
  8. return self.__dict__from app01 import myserial
  1. class Book(APIView):
  2. queryset=models.Book.objects.all()
  3. serializer_class=myserial.BookSer
  4. def get(self,request):
  5. response=MyResponse()
  6. # 多条
  7. # books = models.Book.objects.all()
  8. # ret=myserial.BookSer(books,many=True)
  9. # 一条
  10. book = self.queryset
  11. # ret = myserial.BookSer(book, many=False)
  12. ret = self.serializer_class(instance=book, many=True)
  13. response.msg='查询成功'
  14. response.data=ret.data
  15. return JsonResponse(response.get_dic,safe=False)
  16.  
  17. # return HttpResponse('get')
  18. def post(self,request):
         # return HttpResponse('post')

4、若要进行多对多的查询,book和author,可以用SerializerMethodField方法

  1. - aa=serializers.SerializerMethodField()
  2. -必须配套一个方法(get_aa(self,obj)),方法返回结果,会赋给aa
  3. -在方法内部,可以继续用序列化组件

如下

  1. class BookSer(serializers.Serializer):
  2. nid=serializers.IntegerField()
  3. name3=serializers.CharField(source='name')
  4. price=serializers.CharField()
  5. # publish_date = serializers.DateField()
  6. publish_date = serializers.CharField()
  7. # publish=serializers.CharField(source='publish.email')
  8. publish=serializers.CharField(source='publish.name')
  9. xxx=serializers.CharField(source='test')
  10. # authors=serializers.CharField(source='authors.all')
  11. # SerializerMethodField,可以写一个方法方法名叫:get_字段名字,方法返回值,会赋给authors
  12. aa=serializers.SerializerMethodField()
  13. # def get_authors(self,obj):
  14. # authors=obj.authors.all()
  15. # # ll=[ author.name for author in authors]
  16. # ll=[ {'name':author.name,'age':author.age} for author in authors]
  17. # return ll
  18. def get_aa(self, obj):
  19. authors = obj.authors.all()
  20. # ll=[ author.name for author in authors]
  21. ser=AuthorSer(authors,many=True)
  22. return ser.data
  23.  
  24. class AuthorSer(serializers.Serializer):
  25. id=serializers.IntegerField(source='nid')
  26. age=serializers.CharField()
  27. name=serializers.CharField()

四 序列化组件之serializers.ModelSerializer

  1. -用法同Serializer
  2. -不同点:
  3. class BookSer(serializers.ModelSerializer):
  4. class Meta:
  5. # 指定要序列号的表模型是book
  6. model=models.Book
  7. fields='__all__'
  8. exclude=['nid']
  9. depth=

例子如下

  1. from app01 import models
  2. class BookSer(serializers.ModelSerializer):
  3. class Meta:
  4. # 指定要序列号的表模型是book
  5. model=models.Book
  6. # 把所有字段都序列化
  7. # fields='__all__'
  8. # 可以传列表,指定取几个
  9. # fields=['name','authors','publish']
  10. # 除了nid都查
  11. exclude=['authors']
  12. #fields和exclude不能同时用
  13. # depth指定深度,个人建议最多用3
  14. # depth=

五 序列化组件的字段校验和反序列化功能

序列化组件是将对象序列化成字典,但是前台post提交的json数据需要转成字典,再反序列化成对象,最后save()方法才能保存在数据里,需要反序列功能

  1. -只有:ModelSerializer,能直接保存
  2. - def post(self,request):
  3. print(request.data)
  4. #生成一个序列化对象
  5. ser=myserial.BookSer(data=request.data)
  6. #判断字段是否校验通过
  7. if ser.is_valid():
  8. #通过,直接保存
  9. ser.save()
  10. else:
  11. #错误信息
  12. print(ser.errors)
  13.  
  14. return HttpResponse('post')
  15.  
  1. from app01 import models
    class BookSer(serializers.ModelSerializer):
    class Meta:
    # 指定要序列号的表模型是book
    model=models.Book
    exclude=['authors']

如下

  1. def post(self,request):
  2. # print(request.data)
  3. ser=myserial.BookSer(data=request.data)
  4. if ser.is_valid():
  5. ser.save()
  6. return HttpResponse('成功')
  7. else:
  8. print(ser.errors)
  9.  
  10. return JsonResponse(ser.errors)

六 序列化组件局部校验和全局校验

  1. -局部校验
  2. name=serializers.CharField()
  3. def validate_name(self,value):
  4. if value.startswith('sb'):
  5. raise ValidationError('不能以sb开头')
  6. else:
  7. return value
  8. -全局校验
  9. def validate(self,value):
  10. print(type(value))
  11. print(value)
  12. name=value.get('name')
  13. price=value.get('price')
  14. if name!=price:
  15. raise ValidationError('书名和价格不相等')
  16. else:
  17.  
  18. return value

如下

  1. from rest_framework.exceptions import ValidationError
  2. from app01 import models
  3. class BookSer(serializers.ModelSerializer):
  4. class Meta:
  5. # 指定要序列号的表模型是book
  6. model=models.Book
  7. # 把所有字段都序列化
  8. # fields='__all__'
  9. # 可以传列表,指定取几个
  10. # fields=['name','authors','publish']
  11. # 除了nid都查
  12. exclude=['authors']
  13. #fields和exclude不能同时用
  14. # depth指定深度,个人建议最多用3
  15. # depth=
  16. 局部校验
  17. name=serializers.CharField(error_messages={'required':'该字段必填'})
  18. def validate_name(self,value):
  19. if value.startswith('sb'):
  20. raise ValidationError('不能以sb开头')
  21. else:
  22. return value
  23. 全局校验
  24. def validate(self,value):
  25. print(type(value))
  26. print(value)
  27. name=value.get('name')
  28. price=value.get('price')
  29. if name!=price:
  30. raise ValidationError('书名和价格不相等')
  31. else:
  32.  
  33. return value

views,主要验证前台post提交数据的局部和全局验证

  1. from app01 import myserial
  2. class Book(APIView):
  3. queryset=models.Book.objects.all()
  4. serializer_class=myserial.BookSer
  5. def get(self,request):
  6. response=MyResponse()
  7. # 多条
  8. # books = models.Book.objects.all()
  9. # ret=myserial.BookSer(books,many=True)
  10. # 一条
  11. book = self.queryset
  12. # ret = myserial.BookSer(book, many=False)
  13. ret = self.serializer_class(instance=book, many=True)
  14. response.msg='查询成功'
  15. response.data=ret.data
  16. return JsonResponse(response.get_dic,safe=False)
  17.  
  18. # return HttpResponse('get')
  19. def post(self,request):
  20. # print(request.data)
  21. ser=myserial.BookSer(data=request.data)
  22. if ser.is_valid():
  23. ser.save()
  24. return HttpResponse('成功')
  25. else:
  26. print(ser.errors)
  27.  
  28. return JsonResponse(ser.errors)

七、符合drf的视图类基本写法

1、views.py

  1.  
  1. class MyResponse():
    def __init__(self):
    self.status = 100
    self.msg = None
  2.  
  3. @property
    def get_dic(self):
    return self.__dict__
  1. class BookDetail(APIView):
  2. def get(self,request,id):
  3. response=MyResponse()
  4. ret=models.Book.objects.filter(pk=id).first()
  5. ser=myserial.BookSer(instance=ret,many=False)
  6. response.msg='查询成功'
  7. response.data=ser.data
  8. return JsonResponse(response.get_dic,safe=False)
  9.  
  10. def put(self,request,id):
  11. # 修改
  12. response=MyResponse()
  13. book=models.Book.objects.filter(pk=id).first()
  14. ser=myserial.BookSer(instance=book,data=request.data)
  15. if ser.is_valid():
  16. # 可以新增,可以修改
  17. ser.save()
  18. print(ser.data)
  19. print(type(ser.instance))
  20. response.msg='修改成功'
  21. response.data=ser.data
  22.  
  23. else:
  24. response.msg = '修改失败'
  25. response.status =
  26. response.data=ser.errors
  27. return JsonResponse(response.get_dic,safe=False)
  28.  
  29. def delete(self,request,id):
  30. ret=models.Book.objects.filter(pk=id).delete()
  31. return HttpResponse('删除成功')

2、序列化组件

  1. url(r'^books/(?P<pk>\d+)/', views.BookDetail.as_view()),
  1. from app01 import models
    class BookSer(serializers.ModelSerializer):
    class Meta:
    # 指定要序列号的表模型是book
    model=models.Book
    exclude=['authors']

RESTful规范(一)的更多相关文章

  1. RESTful规范

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

  2. RESTful 规范

    RESTful 规范 前言 rest 是一种软件架构风格,如果使用的是 rest 接口,那么就可以说你的接口是 restful. rest接口是围绕''资源''展开的,利用 HTTP 的协议,其实 r ...

  3. DjangoRestFramework 学习之restful规范 APIview 解析器组件 Postman等

    DjangoRestFramework学习一之restful规范.APIview.解析器组件.Postman等 本节目录 一 预备知识 二 restful规范 三 DRF的APIView和解析器组件 ...

  4. RESTful规范1

    RESTful规范 一 什么是RESTful REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为"表征状 ...

  5. Django restful 规范

    一.REST Frame Work REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为"表征状态转移&q ...

  6. restful 规范(建议)

    需求:开发cmdb,对用户进行管理. 做前后端分离,后端写api(URL),对用户表进行增删改查,应该写四个URL(还要给文档(返回值,返回,请求成功,干嘛,失败,干嘛)),然后分别写视图函数. ht ...

  7. restful规范快速记忆

    restful规范: 十个规则: 用户发来请求,url必须: 1.因为是面向资源编程,所以每个URL代表一种资源,URL中尽量不要用动词,要用名词 2.尽量使用HTTPS,https代替http 3. ...

  8. 一、restful规范 二、CBV(View)源代码执行流程 三、drf框架安装和简单使用

    一.restful规范 ''' 它是一个规范,面向资源架构 十条规范 1.API与用户的通讯协议,总是使用HTTPs协议,确保了网络传输的安全性 2.域名 --https://api.example. ...

  9. drf1 rest & restful规范

    web服务交互 我们在浏览器中能看到的每个网站,都是一个web服务.那么我们在提供每个web服务的时候,都需要前后端交互,前后端交互就一定有一些实现方案,我们通常叫web服务交互方案. 目前主流的三种 ...

  10. django rest framework restful 规范

    内容回顾: . django请求生命周期 -> 执行遵循wsgi协议的模块(socket服务端) -> 中间件(路由匹配) -> 视图函数(业务处理:ORM.模板渲染) -> ...

随机推荐

  1. HTML5 ③

    超链接和锚链接: 1.超链接标签:<a herf="需要连接的页面地址"    target=“01._self :在当前页面打开 *默认值  02. _blank :新窗口 ...

  2. OO第三次课程总结分析

    OO第三次课程总结分析 规格化设计发展历史 在网上找了好久也没找到合适的信息,稍稍参考了同学的博客.大致如下:最初的的软件并没有形式化方法,随着软件工程的兴起,为了便于工程间的协调管理,人们提出采用工 ...

  3. 基于WMI的信息查询和编辑,按微软的说明一般都是

    晕!这个不是很简单的东西吗? //---------WMI---------- type Rec_Wmi = record ComputerName: string; Namespace: strin ...

  4. day34 线程池 协程

    今日内容: 1. 线程的其他方法 2.线程队列(重点) 3.线程池(重点) 4.协程 1.线程的其他方法 语法: Threading.current_thread() # 当前正在运行的线程对象的一个 ...

  5. Mysql中contact、group_concat、concat_ws、repeat

    一.CONCAT(str1,str2,…) 返回结果为连接参数产生的字符串.如有任何一个参数为NULL ,则返回值为 NULL. mysql> select concat('11','22',' ...

  6. html页面小技巧

    #1.onkeyup限制输入框只能输入数字 通过onkeyup事件是输上后再去掉非数字字符 <input type="text" onkeyup="value=va ...

  7. 自动化创建tornado项目

    tornado目录结构: index.py 入口文件 app app目录 |___ __init__.py 初始化脚本 |___ templates  模板目录 |        |___ index ...

  8. merge into用法小结

    CREATE OR REPLACE PROCEDURE PRO_ZXC(O_NO OUT NUMBER,O_NOTE OUT NUMBER)ASBEGIN O_NO:=1; MERGE INTO QQ ...

  9. 从Oracle数据库中的本地命名文件tnsnames.ora来看服务别名、服务名和实例名的区别。

    tnsnames.ora的作用这里就不多述了,各位应该都知道. 首先先看两个例子: test1 = (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCO ...

  10. day 31 udp 协议SOCK_DGRAM

    udp 服务端引用socket=类型,协议绑定地址 和 端口while 循环收到 data addr = 服务.recvfrom(1024)发送 服务.sendto(data,addr(ip 端口)) ...