Django的view:
一个视图函数(类),简称视图,是个简单地Python函数(类),他接受web请求并且返回web响应,响应可以是一张网页HTML内容,一个重定向, 一个是404错误,一个是xml文档,或者是一个图片, 无论视图本身包含什么逻辑,都要返回响应.代码写在哪里都无所谓,只要他在当前的项目目录之下,除此之外没有更多的要求了.为了将代码放在某处,大家约定俗成将视图放置在项目(project)或应用程序(APP)目录中的名为views.py的文件中.
二. FBV与CBV
FBV(function based views), 即基于函数的视图;CBV(class based views)即基于类的视图,也是基于对象的视图.我们之前写过的都是基于函数的view.
当听到基于class时,一脸懵逼,隐隐的感觉有点慌,但还是选择去面对,如果想让我们的代码有水准,那他妈的还是避不开对象,对开发者来说,肯定得用到对象.
先纯手撸一个视图的
from django.shortcuts import render, HttpResponse from django.views import View class myview(View): def get(self, request): return render(request, 'login.html') def post(self, request): return HttpResponse('login')
再纯手来一个登录页面
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> </head> <body> <form action="" method="post"> username:<input type="text" name="username"> <input type="submit"> </form> </body> </html>
从url入手
from Django.contrib import admin from Django.urls import path from app01 import views urlpatterns = [ url('^admin/', admin.site.urls), url('^login/', views.myview.as_view()), # 由于函数名加括号执行优先级最高, 所以这一句话写完就会立即执行as_view()方法 ]
分析过程
首先我们得看url,当请求路径为login时,会调用views里面的myview类的一个方法as_view,在这里我们不管这个方法到底干了啥,只是先走一走流程,在浏览器中输入login路径时,用的是get请求,他就会去调用myview类下的自己写的get,然后渲染一个登陆的页面,得到渲染的页面后输入用户名进行提交,又往login路径发送了一个post请求,这时就会调用myview类下的自己写的post方法,返回一个'login'字符,整个流程大致就是这样的,在整个过程中,Django会判断请求方式,不同的请求方式调用相应的方法.
三. 源码进行解牛
我们自定义的myview类里面没有写任何关于请求方式的逻辑,那应该是myview继承的view类里面肯定有相关的东西
@classonlymethod def as_view(cls, **initkwargs): # cls就是我们自己的写的类 Myview def view(request, *args, **kwargs): self = cls(**initkwargs) # 实例化产生MyLogin的对象 self = Myview(**ininkwargs) if hasattr(self, 'get') and not hasattr(self, 'head'): self.head = self.get self.request = request self.args = args self.kwargs = kwargs # 上面的几句话都仅仅是在给对象新增属性 return self.dispatch(request, *args, **kwargs) # dispatch返回什么 浏览器就会收到什么 # 对象在查找属性或者方法的时候 你一定要默念 先从对象自己这里找 然后从产生对象的类里面找 最后类的父类依次往后 return view # 这是返回view这个方法,也就是把view方法作为返回值作为as_view的返回值 通过源码发现url匹配关系可以变形成 url(r'^login/',views.view) # FBV和CBV在路由匹配上是一致的 都是url后面跟函数的内存地址
当浏览器中输入login会立即触发view函数的运行
def dispatch(self, request, *args, **kwargs): # Try to dispatch to the right method; if a method doesn't exist, # defer to the error handler. Also defer to the error handler if the # request method isn't on the approved list. # 我们先以GET为例 if request.method.lower() in self.http_method_names: # 判断当前请求方法是否在默认的八个方法内 # 反射获取我们自己写的类产生的对象的属性或者方法 # 以GET为例 handler = getattr(self,'get','取不到报错的信息') # handler = get(request) handler = getattr(self, request.method.lower(), self.http_method_not_allowed) else: handler = self.http_method_not_allowed return handler(request, *args, **kwargs) # 直接调用我们自己的写类里面的get方法
比如说是get请求进来后,它就利用反射会去myview里面拿到一个叫get的方法,在我的myview类下就有我自定义的get方法,然后执行它,得到一个HTTPResponse对象,返回给dispatch方法,dispatch方法又把这个HTTPResponse对选哪个返回给了view方法,
view方法又把这个对象返回给as_view方法,as_view方法又把这个作为响应返回给客户端,这整个过程简化中间的过程就会变成,get方法返回一个HTTPResponse对象给客户端
django settings源码
前提:
1.django除了暴露给用户一个settings.py配置文件之外 自己内部还有一个全局的配置文件
2.我们在使用配置文件的时候 可以直接直接导入暴露给用户的settings.py也可以使用django全局的配置文件 并且后者居多from django.conf import settings
3.django的启动入口是manage.py