目录
阅读本文之前请先对Http有一定了解(get/post,状态码)。如果不知道从哪里学起可以先搜一下爬虫教程,看完就会了。有时候我会把函数写成方法,请明白这两个东西在这个教程里是等价的。
视图 文件解析
视图即是view,Django MTV模式里的V。视图在框架中承担着接收请求并构造回应的任务。
打开工程所属的app下的views.py:
from django.shortcuts import render
## 从django.shortcuts导入render方法
from django.http import HttpResponse
## 从django.http导入HttpResponse类
# Create your views here.
## 注释告诉我们从这里创建视图
1 django.shortcuts.render方法
render方法结合一个给定的模板(template)和一个给定的上下文字典, 并返回一个渲染后的HttpResponse对象。这个方法连接了MTV模式中的T(template)和V(view)。
render方法里引用的template文件一般默认在app目录下的templates文件夹下。也就是django会依次寻找所有app下的templates文件夹下路径,并与你写的相对路径做对比。
render(request, template_name, context=None, content_type=None, status=None, using =None )
- -request:与相应相对的请求对象,一般为HttpRequest对象
- -template_name:要渲染并返回的模版的名字
- -context:可为空,期望对象为字典,参与对模版的渲染
- -content_type:默认为text/html,指定渲染出的模版的类型
- -status:默认为200,此相应的http状态码
- -using:可为空,指定用来渲染模版的引擎
2 django.http.HttpResponse类
顾名思义是后端返回给前端的对象。在views.py里定义的函数,无论是FBV还是CBV都要返回HttpResponse对象,可以由render方法生成,也可以直接构造对象返回。
HttpResponse类的常用属性:
- -content:响应内容
- -charset:响应内容的编码
- -status_code:响应的状态码
3 django.http.HttpRequest类
和HttpResponse相对,是前端传给后端的对象,一般由django自动生成。视图从request中获取请求参数和头部内容等,然后生成HttpRequest对象,返回给前端。这实际上就是Http协议的原理(往大一点可不可以说是任何网络通信的原理?不过这方面我了解的很少),发起请求然后接收响应,让浏览器解析显示出来。如果你是用户,那你只要关心点击哪个链接会得到想要的结果;但现在你是服务端,你要关注的就是:用户端发出的请求你需要用上哪些?你通过什么样的运算生成用户端所期望的响应?而怎么发送,怎么接收,这些是django操心的事情。
HttpRequest类的常用属性:
- -path_info:用户访问的url(不包括域名)
- -method:请求使用的HTTP方法的大写
- -GET:如果请求使用的方法是get,这个属性是get所有参数的字典
- -POST:如果请求使用的方法是post,这个属性是post所有参数的字典
- -META:请求头
- -FILES:如果提交的表单中包含文件,这个属性是post中文件的字典,其key为表单中的name属性,value为文件本身
# 重定向
在django中的重定向调用django.shortcuts.redirect方法,或者直接构造一个HttpReponseRedirect对象返回(HttpResponseRedirect类是HttpResponse的子类)。
示例:
from django.shortcuts import redirect
def 重定向函数(request):
return redirect("你要重定向的链接")
from django.http import HttpResponseRedirect
def 重定向函数(request):
return HttpResponseRedirect("你要重定向的链接")
建立视图
Django的视图分为视图类(class based view,CBV)和视图函数(function based view,FBV),他们主要接收POST和GET请求(有一个误区是GET其实也可以接受参数,不过是传递的方式不一样)。前面说过视图接受HttpRequest并返回HttpResponse,那么视图类和视图函数就是视图功能的具体实现。
例1 视图类:
创建的视图类继承django.views.View类。
from django.views import View
class 视图类名(View):
def get(self,request):
pass
def post(self,request,[post参数..]):
pass
get请求与post请求分别由CBV下的两个同名成员方法处理。至于post参数如何传递,请往下看。
例2 视图函数:
def 视图函数名(request,[post参数..]):
if(request.method=="GET"):
pass
elif(request.method=="POST"):
pass
在FBV里,区分get和post请求主要是通过系统传来的HttpRequest的method属性。
UrlPattern 文件解析
UrlPattern指的是项目文件夹下urls.py里定义的一个列表。这个列表决定了客户端访问的url会被映射到哪一个视图处理函数(类)上。
django自动创建的urls.py里的举例:
Examples:
Function views
- Add an import: from my_app import views
- Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
- Add an import: from other_app.views import Home
- Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
- Import the include() function: from django.urls import include, path
- Add a URL to urlpatterns: path('blog/', include('blog.urls'))
1 django.urls.path方法
path(route,view,[name])
- -route:路由,是一个字符串,用来匹配用户访问的url。串中用<>括起来的部分可以作为参数传递到视图
- -view:处理链接的视图类的as_view方法或视图函数
- -name:别名,可选,这个参数起到代替直接的url被引用的作用,也就是说,即使更改了route本身,只要后端引用的name不变,后端就不需要额外的更改。
2 django.urls.re_path方法
re_path(route,view,[name])
- -其他参数跟path的一样,route从字符串变成正则表达式
# django.urls.include方法
根据上面django内置的例子,include方法用于在path方法中包括另一个URLConf,也就是另一个url文件。父URLConf的path过滤了第一个router,然后将请求url转交给include指向的子URLConf。
include(urlconf)
- -urlconf:指向的子URL文件
url与view的配合例子
例1 视图类与字符串pattern的url带参get、post:
示例项目根路径下urls.py:
from helloworld import views
urlpatterns = [
path("firsturl/<arg1>",views.First.as_view())
]
子app helloworld下views.py:
class First(View):
def get(self,request,arg1):
return HttpResponse("收到了"+arg1)
def post(self,request,arg1):
return render(request,"我的html.html",{"arg1":arg1})
由于模版的编写不在本文范围内就不展示了。项目下打开命令行runserver在127.0.0.1:8000下运行django,输入127.0.0.1:8000/firsturl/1,可以收到页面显示的“收到了1”。由于post请求不好在浏览器直接实现就不表。
例2 视图函数与post接受表单:
示例项目根路径下urls.py的urlpatterns添加一行:
path("secondurl",views.Second.as_view())
子app helloworld下views.py:
def second(request):
if(request.method=="GET"):
return render(request,"我的html.html")
if(request.method=="POST"):
return HttpResponse("收到了"+request.POST["submit1"])
子app helloworld下文件夹templates下我的html.html:
<!doctype html>
<html>
<head></head>
<body>
<form method="post">
{% csrf_token %}<!--因为我们设置里默认启用中间件django.middleware.csrf.CsrfViewMiddleware-->
请输入:<input name="submit1">
</form>
</body>
</html>
是不是觉得它跟普通的html文件有所不同?这是因为它使用了django的模版语言,这个内容我们在下一部分会讲解。项目下打开命令行runserver在127.0.0.1:8000下运行django,输入127.0.0.1:8000/secondurl,可以看到一个输入框,输入一然后enter提交(在这里浏览器对本页面发送了POST请求),可以看到浏览器显示“收到了1”。