REST framework---基于类的视图
一、程序设计
1.路由设计
from django.conf.urls import url
from django.contrib import admin
from app import views
from django.views import View urlpatterns = [
url(r'^admin/', admin.site.urls), # 基于类的视图
url(r'^login/', views.LoginView.as_view()),
url(r'^logout/', views.LogoutView.as_view()), ]
2.模型设计
from django.contrib.auth.models import AbstractUser
class UserInfo(AbstractUser):
"""
用户信息表
"""
nid = models.AutoField(primary_key=True)
phone = models.CharField(max_length=11,
null=True,
unique=True,
) def __str__(self):
return self.username class Meta:
verbose_name = "用户信息"
verbose_name_plural = verbose_name # 不要忘记在setting.py中引用Django的UserInfo表
# 引用Django自带的UserInfo表,继承使用时需要设置
AUTH_USER_MODEL = "app.UserInfo"
3.视图设计
from django.views import View
class LoginView(View): def get(self, request, *args, **kwargs):
form_obj = forms.LoginForm()
return render(request, "login.html", {"form_obj": form_obj},) def post(self, request, *args, **kwargs):
ret = {"code": 0}
# 获取用户输入的用户名、密码
username = request.POST.get("username")
password = request.POST.get("password")
# 判断用户是否存在以及认证
user_obj = auth.authenticate(username=username,
password=password)
if user_obj:
# 登录
auth.login(request, user_obj) # 认证成功后可跳转的地址
ret["data"] = "/index/"
else:
# 认证失败
ret["code"] = 1
ret["data"] = "用户名或密码错误" return JsonResponse(ret) class LogoutView(View):
# 退出登录
def get(self, request, *args, **kwargs):
auth.logout(request)
return redirect("/login/")
二、View源码解析
1.基于函数的视图中,URL设计中,当接收到客户端请求时根据正则匹配得到相应的视图函数并执行,然后得到相应的HttpResponse响应
url(r'^login/', views.login),
2.基于类的视图中,最终也是将函数的执行结果返回给客户端,不同的是当接收到客户端请求时,根据类调用类中的方法,由类的继承、封装、多态、属性查找等特性最终得到相应的HttpResponse响应
url(r'^login/', views.LoginView.as_view()),
看源码(展示中将部分源码省略):
1)客户端发起请求,省略前边一系列中间件等流程,进行路由解析的时候,通过路由匹配拿到对应的类,发现
拿到的是一个对象.属性的方法,于是进行类的属性查找
class LoginView(View):
def get(self, request, *args, **kwargs):
...
def post(self, request, *args, **kwargs):
...
2)发现该视图类中没有 as_view() 这个方法,于是根据属性查找关系到继承的类View中查找
class View(object):
http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
@classonlymethod
def as_view(cls, **initkwargs):
def view(request, *args, **kwargs):
return self.dispatch(request, *args, **kwargs)
return view
3)函数中的self为当前的访问到的LoginView对象,在上面的view()方法中返回时遇到self.dispatch(),于是有经过一次属性查找,子类中找不到又再次来到View父类中查找dispatch()方法,最终得到以下
def dispatch(self, request, *args, **kwargs):
if request.method.lower() in self.http_method_names:
handler = getattr(self, request.method.lower(), self.http_method_not_allowed)return handler(request, *args, **kwargs)
4)最终通过反射的方式从View类定义的HTTP请求方法和类视图LoginView中对应的方法,获取到HttpResponse响应返回给客户端
以上是Django中内置的类视图方法,还可以通过安装restframework模块,继承其模块内的APIView类实现:
1)APIView实际上继承的也是Django内置的View类
2)获取HttpResponse响应返回给客户端的过程与之前解析的方法相同,区别在于经过属性查找原则最终调用dispatch()方法时,调用的是REST framework内的自定义的dispatch()
def dispatch(self, request, *args, **kwargs):
"""
`.dispatch()` is pretty much the same as Django's regular dispatch,
but with extra hooks for startup, finalize, and exception handling.
"""
self.args = args
self.kwargs = kwargs
request = self.initialize_request(request, *args, **kwargs)
self.request = request
self.headers = self.default_response_headers # deprecate? try:
self.initial(request, *args, **kwargs) # Get the appropriate handler method
if request.method.lower() in self.http_method_names:
handler = getattr(self, request.method.lower(),
self.http_method_not_allowed)
else:
handler = self.http_method_not_allowed response = handler(request, *args, **kwargs) except Exception as exc:
response = self.handle_exception(exc) self.response = self.finalize_response(request, response, *args, **kwargs)
return self.response
通过属性查找等规则,最后得到一个HttpResponse相应,不同的是在使用REST famework模块时,可在调用dispatch()方法时实现REST framework提供的其它功能
官方网站:
http://www.django-rest-framework.org/
第三方翻译的中文文档:
https://q1mi.github.io/Django-REST-framework-documentation/
REST framework---基于类的视图的更多相关文章
- Django REST FrameWork中文教程3:基于类的视图
我们也可以使用基于类的视图编写我们的API视图,而不是基于函数的视图.我们将看到这是一个强大的模式,允许我们重用常用功能,并帮助我们保持代码DRY. 使用基于类的视图重写我们的API 我们将首先将根视 ...
- Django编写RESTful API(三):基于类的视图
欢迎访问我的个人网站:www.comingnext.cn 前言 在上一篇文章中,主要讲的是请求和响应,项目里面views.py中的视图函数都是基于函数的,并且我们介绍了@api_view这个很有用的装 ...
- django-rest-framework之基于类的视图
前言:上一篇博客中,主要讲的是请求和响应,项目里面views.py中的视图函数都是基于函数的,并且我们介绍了@api_view这个很有用的装饰器.同时,我们还介绍了APIView这个类,但是还没使用它 ...
- django 中基于类的视图
django 视图 分为两种: 1. FBV 基于函数的视图 function based view 2. CBV 基于类的视图 class based ...
- 介绍——基于类的视图(class-based view)
刚开始的时候,django只有基于函数的视图(Function-based views).为了解决开发视图中繁杂的重复代码,基于函数的通用视图( Class-based generic views) ...
- Django 基于类的视图(CBV)执行流程 CBV 源码分析
一.CBV(基于类的视图) 视图是可以调用的,它接受请求并返回响应,这不仅仅是一个函数,Django提供了一些可以用作视图的类的例子,这些允许您通过继承或mixin来构建视图并重用代码. 基本示例 D ...
- Django——基于类的视图源码分析 一
基于类的视图(Class-based view)是Django 1.3引入的新的视图编写方式,用于取代以前基于函数(Function-based)方式. 借助于OO和Python中方便的多重继承特性, ...
- Django——基于类的视图源码分析 二
源码分析 抽象类和常用视图(base.py) 这个文件包含视图的顶级抽象类(View),基于模板的工具类(TemplateResponseMixin),模板视图(TemplateView)和重定向视图 ...
- Django——基于类的视图(class-based view)
刚开始的时候,django只有基于函数的视图(Function-based views).为了解决开发视图中繁杂的重复代码,基于函数的通用视图( Funcation-based generic vie ...
- 运维开发笔记整理-基于类的视图(CBV)
运维开发笔记整理-基于类的视图(CBV) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.FBV与CBV 1>.什么是FBV FBC(function base views ...
随机推荐
- Lesnoe Ozero 2016. BSUIR Open 2016 Finals
A. Street magic 数位DP,设$f[i][j][k]$表示从低到高考虑$x$的后$i$位,$x$和$m$大小关系为$j$,和$n$大小关系为$k$的方案数. #include<cs ...
- session 存到memcache里
web服务器的php session都给memcached ,这样你不管分发器把 ip连接分给哪个web服务器都不会有问题了,配置方法很简单,就在php的配置文件内 增加一条语句就可以了,不过前提你需 ...
- mobile_基础事件
DOM0 级事件模型(模拟器不支持) DOM0 级事件绑定 在 移动端有 300ms 的延迟 ontouchstart 手指按下事件 ontouchmove 手指移动事件 pntouchend 手指离 ...
- Java课后作业之石家庄地铁系统PSP表格20190403
PSP2.1 Personal Software Process Stages Time Planning 计划 36 hours · Estimate · 估计这个任务需要多少时间 36 hours ...
- 日期求星期(java)-蓝桥杯
日期求星期问题(java)-蓝桥杯 1:基姆拉尔森计算公式(计算星期) 公式: int week = (d+2*m+3*(m+1)/5+y+y/4-y/100+y/400)%7; 此处y,m,d指代年 ...
- Jquery常用的方法总结
1.关于页面元素的引用通过jquery的$()引用元素包括通过id.class.元素名以及元素的层级关系及dom或者xpath条件等方法,且返回的对象为jquery对象(集合对象),不能直接调用dom ...
- SourceTree安装跳过登录
安装 SourceTree 时,需要使用atlassian授权,因为各种原因无法完成授权,现提供跳过 atlassian账号 授权方法. 安装之后,转到用户本地文件夹下的 SourceTree 目录, ...
- 课堂动手动脑String
一 public class StringPool { public static void main(String args[]) { String s0="Hello"; St ...
- python中关于汉诺塔问题和使用turtle库实现其搬运过程
一.汉诺塔问题 汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具.大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘.大梵天命令婆罗门把圆盘从下面开始按 ...
- [dev][socket] unix domain socket删除socket文件
问题 在使用unix domain socket的时候,bind之后,会在本地路径里 产生一个与path对应的socket文件. 如何正确的在用完socket之后,对其销毁呢? 方案 使用 unlin ...