Rest Framework

Rest Framework

django请求生命周期

1.先进入实现了wsgi协议的web服务器
2.进入django
3.经过中间件、路由、视图
4.再取模板、取数据、用数据渲染模板
5.返回模板的字符串

开发模式

​ 1.前后端不分离项目(BBS)

​ 2.前后端分离项目

​ 前端和后端通过json格式数据交互

cbv源码分析

1.路由配置:url(r'^text/',views.Text.as_view())
2.请求通过中间件进入路由,根据路由匹配,一旦成功,会执行后面的函数(views.Text.as_view()(request)),本质就是执行了as_view内部的view函数
3.内部又调用了self.dispatch,根据请求方式,执行不同的方法(如果是get请求,就会执行我们写的视图类的get方法)

restful规范:面向资源架构

1.API与用户的通信协议,总是使用HTTPs协议
2.域名有区分
	https://api.example.com
	https://example.org.api
3.版本(v1,v2)
	可以放在路径中
		https://api.example.com/v1/
	可以放在请求头中
4.路径
	视网络上任何东西都是资源,均使用名词表示(重点)
	https://api.example.com/v1/books
5.通过method区分是什么操作
	get表示获取
	post表示新增
	put/patch表示更新(修改)
	delete表示删除
6.过滤
	通过在url上传参的形式传递搜索条件
7.状态码
	{"status_code":100}
8.错误处理,应返回错误信息
	{"status_code":100,"msg":"登入成功"}
	{"status_code":101,"msg":"用户名错误"}
9.返回结果,针对不同操作,服务器向用户返回的结果
	127.0.0.1/api/vi/books  获取所有图书
	{"status_code":100,'msg':'获取成功',data:[{},{}]}
	
	127.0.0.1/api/vi/books/3  获取id为3的图书
	{"status_code":100,'msg':'获取成功',data:{name:xx,....}}
	
	新增数据,把新增的数据再返回
	修改了数据,返回完整的资源对象
	删除数据,返回一个空文档
10.返回结果中提供链接
	

基于原生Django开发restful的接口

from app01 import views
from django.http import JsonResponse
def test(request):
    if request.method == 'GET':
    	book_list = models.Books.objects.all()
    	l = [{'name':book.name,'publish':book.publish} for book in book_list]
    	response = {'code':100,'msg':'查询成功','data':l}
        #safe=False,如果要序列化的对象中有列表需要设置
        #json_dumps_params={'ensure_ascii':False},如果要序列化的对象中有中文需要设置
    	return JsonResponse(response,safe=False,json_dumps_params={'ensure_ascii':False})

drf:APIView的源码,Request的源码

安装:pip3 install djangorestframework

使用:

第一步:再写视图,都写cbv

from rest_framework.views import APIView
class Books(APIView):
    pass

第二步:在settings中配置

INSTALLED_APPS= [
。。。。。
'rest_framework'
]

源码分析

继承了APIView之后:
	1.所有的请求都没有csrf的认证了
	2.在APIView中as_view本质还是调用了父类的as_view(View的as_view)
	3.as_view中调用dispatch(调用的是APIView中的disptch)

APIView的dispatch方法:
	1.对原生request对象做了一层包装(面向对象的封装),原生的request在request._request中,以后再用的request对象都是新的request对象
	2.在APIView中self.initial(request,*args,**kwargs),里面有频率控制,权限控制和认证相关
	3.根据请求方法执行视图类中相应的方法(视图类中方法的request对象,已经变成了封装后的request)
Request类:
	1.原生的request是self._request
	2.取post形式提交的数据,从request.data中取(支持urlencoded,formdata,json格式),而原生的request.POST取不到json格式的数据
	3.query_params就是原生request的GET的数据
	4.上传的文件从FILES中取
	5.(重点)其他的属性,直接request.属性名(因为重写了__getattr__方法)

了解

1.wsgi和cgi:通用网关协议

​ 实现了wsgi协议的web服务器:uwsgi

​ 对应到java中就是tomcat

2.跨域:

​ 浏览器从一个域名的网页去请求另一个域名的资源时,域名、端口、协议任一不同,都是跨域

​ 对于想要利用django框架实现前后端分离,首要的问题是解决跨域请求的问题

​ 解决方案:

​ 1.JSONP,比较原始的方法,本质上是利用html的一些不受同源策略影响的标签,从而实现跨域请求,但是这种方法只支持GET的请求方式

​ 2.CORS,Cross-Origin Resource Sharing,是一个新的w3c标准,它新增的一组HTTP首部字段,允许服务端声明哪些源站有权限访问哪些资源,换言之,它允许浏览器向声明了cors的跨域服务器发出XML,HTTPResponse请求,从而克服ajax只能同源使用的限制,在django框架中就是利用cors来解决跨域请求的问题

​ 安装:pip install django-cors-headers

​ 修改django项目中的setting.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'corsheaders',#这是我们的主角,放在新建的其他项目之前
    'app01',
]
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'corsheaders.middleware.CorsMiddleware', #注意顺序,必须放在这儿
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

CORS_ALLOW_CREDENTIALS = True #允许携带cookie

CORS_ORIGIN_ALLOW_ALL = True #允许所有域名跨域

# 允许所有的请求头

CORS_ALLOW_HEADERS = (' * ')

3.301重定向和302重定向的区别

302重定向只是暂时的重定向,搜索引擎会抓取新的内容而保留旧的地址,因为服务器返回302,所以搜索引擎认为新的网址是暂时的

301重定向是永久的重定向,搜索引擎在抓取新的内容的同时也将旧的网址替换为重定向之后的网址

4.django中自定义表名及字段名称

在meta 类中指定表名,在字段中通过db_column指定列名
class Record(models.Model):
    content=models.CharField(max_length=32,db_column='record_content')
    class Meta:
        db_table="Record"

5.对象['xx'] 取值,会触发__getitem__方法

对象['xx'] =10 设置值,会触发__setitem__方法

6.with所求值的对象必须有一个__enter__()方法,一个__exit__()方法。

紧跟with后面的语句被求值后,返回对象的__enter__()方法被调用,这个方法的返回值将被赋值给as后面的变量。当with后面的代码块全部被执行完之后,将调用前面返回对象的__exit__()方法

posted @ 2019-07-01 21:50  ymg-颜  阅读(312)  评论(0编辑  收藏  举报