RESTful规范(一)
一、学习restframework之前准备
1、json格式若想展示中文,需要ensure_ascii=False
- import json
- dic={'name':'你好'}
- print(json.dumps(dic,ensure_ascii=False))
2、不基于restframework也可以通过django来做符合restframework的规范接口设计,Jsonresponse,若想在json展示中文,如下
- def books(request):
- ll=[{'name':'python全站开发','price':},{'name':'linux','price':}]
- # return HttpResponse(json.dumps(ll))
- return JsonResponse(ll,safe=False,json_dumps_params={'ensure_ascii':False})
3、原声cbv执行流程
- url(r'^books/$', views.Book.as_view()),
- 原声cbv执行流程---》as_view----》dispatch---》相应到具体的函数
- from django.views import View
- class Book(View):
- def get(self,reuquest):
- # reuquest.method
- return HttpResponse('get')
- def post(self,request):
- return HttpResponse('post')
3、分析restframework
- 一 restfu(规范)
- 是什么:
- -面向资源编程
- -getBooklist:获取图书列表
- -符合规范的:books
- 规范:
- -method:get----》books----》取到所有的书
- post———》books---》新增图书
- put/patch--》books/id---》修改图书
- delete---》books/id---》删除图书
- -https://api.example.com/v1/zoos?limit=10
- -
- 二 drf
- 安装(app):pip3 install djangorestframework
- -基于drf写resful的接口,得写CBV
- -request对象,源码分析
- -APIView源码分析
二、restframework使用
1、POST没法解析json格式,可以在body里取值出来序列化反序列化操作转成字典,目前drf可以在前台提交post后台取值的话用data,
- from rest_framework.views import APIView
- class Book(APIView):
- def get(self,request):
- # 拿原来的request对象
- # request._request
- # print(request.method)
- # print(request._request.method)
- # request.POST
- # request.method
- return HttpResponse('get')
- def post(self,request):
- print(request.method)
- print(request._request.method)
- print(request.POST)
- # 用apiview之后,再取数据,从request.data
- print(request.data)
- return HttpResponse('post')
2、用Postman模拟发http请求,网上直接下载,data可以类似于解析器,解析form-data,urlencoded,json格式,而django只能解析form-data,urlencoded两种格式
三、序列化组件
1、从数据库取出来的都是qs类型,里面套了一个一个对象,要传到前台去必须要json格式,符合drf规范的第一种方式
- 数据库配置
DATABASES = {- 'default': {
- 'ENGINE': 'django.db.backends.mysql',
- 'NAME': 'resful',
- 'USER':'root',
- 'PASSWORD':'',
- 'HOST':'127.0.0.1',
- 'PORT':,
- }
- }
models取值为qureryset类型,
- from app01 import models
- 序列化组建
- 第一种方式
- class Book(APIView):
- def get(self,request):
- response={'status':,'msg':None}
- books=models.Book.objects.all()
- # ll=[]
- # for book in books:
- # ll.append({'name':book.name,''})
- ll=[ {'name':book.name,'price':book.price} for book in books]
- response['msg']='查询成功'
- response['data']=ll
- return JsonResponse(response,safe=False)
- # return HttpResponse('get')
- def post(self,request):
- return HttpResponse('post')
2、第二种方式,用django子自带序列化组件serializers(Django内置的serializers(把对象序列化成json字符串),但是有个缺点不能定制化
- from django.core import serializers
- class Book(APIView):
- def get(self,request):
- # response={'status':,'msg':None}
- books = models.Book.objects.all()
- ret = serializers.serialize("json", books)
- return HttpResponse(ret)
- # return HttpResponse('get')
- def post(self,request):
- return HttpResponse('post')
3、用drf自带的组件,建议的话新建个py在APP下,方便解耦,如myserial.py,为符合drf格式,里面新建个response类,见下
- - 导入:from rest_framework import serializers
- - 写一个类(名字任意),继承serializers.Serializer
- class BookSer(serializers.Serializer):
- nid=serializers.IntegerField()
- name3=serializers.CharField(source='name')
- price=serializers.CharField()
- # publish_date = serializers.DateField()
- publish_date = serializers.CharField()
- # publish=serializers.CharField(source='publish.email')
- publish=serializers.CharField(source='publish.name')
- xxx=serializers.CharField(source='test')
- - 如果不指定source,字段名,必须跟数据库列名一致
- - source--》既可以指定数据属性,又可以指定方法属性,可以写(publish.name)
- - 使用:
- -查询出要序列化的数据:books = models.Book.objects.all()
- -ret=myserial.BookSer(books,many=True)-----》多条(queryset对象),必须指定many=True
- -ret=myserial.BookSer(books,many=False)-----》一条(Book对象),必须指定many=False
- - aa=serializers.SerializerMethodField()
- -必须配套一个方法(get_aa(self,obj)),方法返回结果,会赋给aa
- -在方法内部,可以继续用序列化组件
myserial.py
- from rest_framework import serializers
- class BookSer(serializers.Serializer):
- nid=serializers.IntegerField()
- name3=serializers.CharField(source='name')
- price=serializers.CharField()
- # publish_date = serializers.DateField()
- publish_date = serializers.CharField()
- # publish=serializers.CharField(source='publish.email')
- publish=serializers.CharField(source='publish.name')
- xxx=serializers.CharField(source='test')
- # authors=serializers.CharField(source='authors.all')
- # SerializerMethodField,可以写一个方法方法名叫:get_字段名字,方法返回值,会赋给authors
- aa=serializers.SerializerMethodField()
- # def get_authors(self,obj):
- # authors=obj.authors.all()
- # # ll=[ author.name for author in authors]
- # ll=[ {'name':author.name,'age':author.age} for author in authors]
- # return ll
- def get_aa(self, obj):
- authors = obj.authors.all()
- # ll=[ author.name for author in authors]
- ser=AuthorSer(authors,many=True)
- return ser.data
models.py
- class Book(models.Model):
- nid = models.AutoField(primary_key=True)
- name = models.CharField(max_length=)
- price = models.DecimalField(max_digits=, decimal_places=)
- publish_date = models.DateField(auto_now_add=True)
- publish = models.ForeignKey(to='Publish',to_field='nid',on_delete=models.CASCADE)
- authors=models.ManyToManyField(to='Author')
- def test(self):
- return 'ttttttt'
- def __str__(self):
- return self.name
使用,为符合drf格式,里面新建个response类,@property让类方法变属性,不需要(),直接点+属性就ok了
- class MyResponse():
- def __init__(self):
- self.status =
- self.msg = None
- @property
- def get_dic(self):
- return self.__dict__from app01 import myserial
- class Book(APIView):
- queryset=models.Book.objects.all()
- serializer_class=myserial.BookSer
- def get(self,request):
- response=MyResponse()
- # 多条
- # books = models.Book.objects.all()
- # ret=myserial.BookSer(books,many=True)
- # 一条
- book = self.queryset
- # ret = myserial.BookSer(book, many=False)
- ret = self.serializer_class(instance=book, many=True)
- response.msg='查询成功'
- response.data=ret.data
- return JsonResponse(response.get_dic,safe=False)
- # return HttpResponse('get')
- def post(self,request):
# return HttpResponse('post')
4、若要进行多对多的查询,book和author,可以用SerializerMethodField方法
- - aa=serializers.SerializerMethodField()
- -必须配套一个方法(get_aa(self,obj)),方法返回结果,会赋给aa
- -在方法内部,可以继续用序列化组件
如下
- class BookSer(serializers.Serializer):
- nid=serializers.IntegerField()
- name3=serializers.CharField(source='name')
- price=serializers.CharField()
- # publish_date = serializers.DateField()
- publish_date = serializers.CharField()
- # publish=serializers.CharField(source='publish.email')
- publish=serializers.CharField(source='publish.name')
- xxx=serializers.CharField(source='test')
- # authors=serializers.CharField(source='authors.all')
- # SerializerMethodField,可以写一个方法方法名叫:get_字段名字,方法返回值,会赋给authors
- aa=serializers.SerializerMethodField()
- # def get_authors(self,obj):
- # authors=obj.authors.all()
- # # ll=[ author.name for author in authors]
- # ll=[ {'name':author.name,'age':author.age} for author in authors]
- # return ll
- def get_aa(self, obj):
- authors = obj.authors.all()
- # ll=[ author.name for author in authors]
- ser=AuthorSer(authors,many=True)
- return ser.data
- class AuthorSer(serializers.Serializer):
- id=serializers.IntegerField(source='nid')
- age=serializers.CharField()
- name=serializers.CharField()
四 序列化组件之serializers.ModelSerializer
- -用法同Serializer
- -不同点:
- class BookSer(serializers.ModelSerializer):
- class Meta:
- # 指定要序列号的表模型是book
- model=models.Book
- fields='__all__'
- exclude=['nid']
- depth=
例子如下
- from app01 import models
- class BookSer(serializers.ModelSerializer):
- class Meta:
- # 指定要序列号的表模型是book
- model=models.Book
- # 把所有字段都序列化
- # fields='__all__'
- # 可以传列表,指定取几个
- # fields=['name','authors','publish']
- # 除了nid都查
- exclude=['authors']
- #fields和exclude不能同时用
- # depth指定深度,个人建议最多用3
- # depth=
五 序列化组件的字段校验和反序列化功能
序列化组件是将对象序列化成字典,但是前台post提交的json数据需要转成字典,再反序列化成对象,最后save()方法才能保存在数据里,需要反序列功能
- -只有:ModelSerializer,能直接保存
- - def post(self,request):
- print(request.data)
- #生成一个序列化对象
- ser=myserial.BookSer(data=request.data)
- #判断字段是否校验通过
- if ser.is_valid():
- #通过,直接保存
- ser.save()
- else:
- #错误信息
- print(ser.errors)
- return HttpResponse('post')
- from app01 import models
class BookSer(serializers.ModelSerializer):
class Meta:
# 指定要序列号的表模型是book
model=models.Book
exclude=['authors']
如下
- def post(self,request):
- # print(request.data)
- ser=myserial.BookSer(data=request.data)
- if ser.is_valid():
- ser.save()
- return HttpResponse('成功')
- else:
- print(ser.errors)
- return JsonResponse(ser.errors)
六 序列化组件局部校验和全局校验
- -局部校验
- name=serializers.CharField()
- def validate_name(self,value):
- if value.startswith('sb'):
- raise ValidationError('不能以sb开头')
- else:
- return value
- -全局校验
- def validate(self,value):
- print(type(value))
- print(value)
- name=value.get('name')
- price=value.get('price')
- if name!=price:
- raise ValidationError('书名和价格不相等')
- else:
- return value
如下
- from rest_framework.exceptions import ValidationError
- from app01 import models
- class BookSer(serializers.ModelSerializer):
- class Meta:
- # 指定要序列号的表模型是book
- model=models.Book
- # 把所有字段都序列化
- # fields='__all__'
- # 可以传列表,指定取几个
- # fields=['name','authors','publish']
- # 除了nid都查
- exclude=['authors']
- #fields和exclude不能同时用
- # depth指定深度,个人建议最多用3
- # depth=
- 局部校验
- name=serializers.CharField(error_messages={'required':'该字段必填'})
- def validate_name(self,value):
- if value.startswith('sb'):
- raise ValidationError('不能以sb开头')
- else:
- return value
- 全局校验
- def validate(self,value):
- print(type(value))
- print(value)
- name=value.get('name')
- price=value.get('price')
- if name!=price:
- raise ValidationError('书名和价格不相等')
- else:
- return value
views,主要验证前台post提交数据的局部和全局验证
- from app01 import myserial
- class Book(APIView):
- queryset=models.Book.objects.all()
- serializer_class=myserial.BookSer
- def get(self,request):
- response=MyResponse()
- # 多条
- # books = models.Book.objects.all()
- # ret=myserial.BookSer(books,many=True)
- # 一条
- book = self.queryset
- # ret = myserial.BookSer(book, many=False)
- ret = self.serializer_class(instance=book, many=True)
- response.msg='查询成功'
- response.data=ret.data
- return JsonResponse(response.get_dic,safe=False)
- # return HttpResponse('get')
- def post(self,request):
- # print(request.data)
- ser=myserial.BookSer(data=request.data)
- if ser.is_valid():
- ser.save()
- return HttpResponse('成功')
- else:
- print(ser.errors)
- return JsonResponse(ser.errors)
七、符合drf的视图类基本写法
1、views.py
- class MyResponse():
def __init__(self):
self.status = 100
self.msg = None- @property
def get_dic(self):
return self.__dict__
- class BookDetail(APIView):
- def get(self,request,id):
- response=MyResponse()
- ret=models.Book.objects.filter(pk=id).first()
- ser=myserial.BookSer(instance=ret,many=False)
- response.msg='查询成功'
- response.data=ser.data
- return JsonResponse(response.get_dic,safe=False)
- def put(self,request,id):
- # 修改
- response=MyResponse()
- book=models.Book.objects.filter(pk=id).first()
- ser=myserial.BookSer(instance=book,data=request.data)
- if ser.is_valid():
- # 可以新增,可以修改
- ser.save()
- print(ser.data)
- print(type(ser.instance))
- response.msg='修改成功'
- response.data=ser.data
- else:
- response.msg = '修改失败'
- response.status =
- response.data=ser.errors
- return JsonResponse(response.get_dic,safe=False)
- def delete(self,request,id):
- ret=models.Book.objects.filter(pk=id).delete()
- return HttpResponse('删除成功')
2、序列化组件
- url(r'^books/(?P<pk>\d+)/', views.BookDetail.as_view()),
- from app01 import models
class BookSer(serializers.ModelSerializer):
class Meta:
# 指定要序列号的表模型是book
model=models.Book
exclude=['authors']
RESTful规范(一)的更多相关文章
- RESTful规范
一. 什么是RESTful REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为“表征状态转移” REST从资源的角 ...
- RESTful 规范
RESTful 规范 前言 rest 是一种软件架构风格,如果使用的是 rest 接口,那么就可以说你的接口是 restful. rest接口是围绕''资源''展开的,利用 HTTP 的协议,其实 r ...
- DjangoRestFramework 学习之restful规范 APIview 解析器组件 Postman等
DjangoRestFramework学习一之restful规范.APIview.解析器组件.Postman等 本节目录 一 预备知识 二 restful规范 三 DRF的APIView和解析器组件 ...
- RESTful规范1
RESTful规范 一 什么是RESTful REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为"表征状 ...
- Django restful 规范
一.REST Frame Work REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为"表征状态转移&q ...
- restful 规范(建议)
需求:开发cmdb,对用户进行管理. 做前后端分离,后端写api(URL),对用户表进行增删改查,应该写四个URL(还要给文档(返回值,返回,请求成功,干嘛,失败,干嘛)),然后分别写视图函数. ht ...
- restful规范快速记忆
restful规范: 十个规则: 用户发来请求,url必须: 1.因为是面向资源编程,所以每个URL代表一种资源,URL中尽量不要用动词,要用名词 2.尽量使用HTTPS,https代替http 3. ...
- 一、restful规范 二、CBV(View)源代码执行流程 三、drf框架安装和简单使用
一.restful规范 ''' 它是一个规范,面向资源架构 十条规范 1.API与用户的通讯协议,总是使用HTTPs协议,确保了网络传输的安全性 2.域名 --https://api.example. ...
- drf1 rest & restful规范
web服务交互 我们在浏览器中能看到的每个网站,都是一个web服务.那么我们在提供每个web服务的时候,都需要前后端交互,前后端交互就一定有一些实现方案,我们通常叫web服务交互方案. 目前主流的三种 ...
- django rest framework restful 规范
内容回顾: . django请求生命周期 -> 执行遵循wsgi协议的模块(socket服务端) -> 中间件(路由匹配) -> 视图函数(业务处理:ORM.模板渲染) -> ...
随机推荐
- HTML5 ③
超链接和锚链接: 1.超链接标签:<a herf="需要连接的页面地址" target=“01._self :在当前页面打开 *默认值 02. _blank :新窗口 ...
- OO第三次课程总结分析
OO第三次课程总结分析 规格化设计发展历史 在网上找了好久也没找到合适的信息,稍稍参考了同学的博客.大致如下:最初的的软件并没有形式化方法,随着软件工程的兴起,为了便于工程间的协调管理,人们提出采用工 ...
- 基于WMI的信息查询和编辑,按微软的说明一般都是
晕!这个不是很简单的东西吗? //---------WMI---------- type Rec_Wmi = record ComputerName: string; Namespace: strin ...
- day34 线程池 协程
今日内容: 1. 线程的其他方法 2.线程队列(重点) 3.线程池(重点) 4.协程 1.线程的其他方法 语法: Threading.current_thread() # 当前正在运行的线程对象的一个 ...
- Mysql中contact、group_concat、concat_ws、repeat
一.CONCAT(str1,str2,…) 返回结果为连接参数产生的字符串.如有任何一个参数为NULL ,则返回值为 NULL. mysql> select concat('11','22',' ...
- html页面小技巧
#1.onkeyup限制输入框只能输入数字 通过onkeyup事件是输上后再去掉非数字字符 <input type="text" onkeyup="value=va ...
- 自动化创建tornado项目
tornado目录结构: index.py 入口文件 app app目录 |___ __init__.py 初始化脚本 |___ templates 模板目录 | |___ index ...
- merge into用法小结
CREATE OR REPLACE PROCEDURE PRO_ZXC(O_NO OUT NUMBER,O_NOTE OUT NUMBER)ASBEGIN O_NO:=1; MERGE INTO QQ ...
- 从Oracle数据库中的本地命名文件tnsnames.ora来看服务别名、服务名和实例名的区别。
tnsnames.ora的作用这里就不多述了,各位应该都知道. 首先先看两个例子: test1 = (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCO ...
- day 31 udp 协议SOCK_DGRAM
udp 服务端引用socket=类型,协议绑定地址 和 端口while 循环收到 data addr = 服务.recvfrom(1024)发送 服务.sendto(data,addr(ip 端口)) ...