python的views文件有什么用_不求甚解系列,快速上手python Django框架3.0(三)探究VIEWS...

上一期我们讲了如何配置URL,本期将进入MTV的讲解。

Django对传统的MVC设计模式进行了修改,将视图分成View模块和Template模块两部分,将动态的逻辑处理与静态的页面展示分离开。而Model采用了ORM技术,将关系型数据库表抽象成面向对象的Python类,将数据库的表操作转换成Python的类操作,避免了编写复杂的SQL语句。

模型(Model):和MVC中的定义一样

模板(Template):将模型数据与HTML页面结合起来的引擎

视图(View):负责实际的业务逻辑实现

一张图表示:

将从URLconf以及M,T,V四个方面详细介绍一个用户请求到响应的中间过程,以及如何编写view,model和template的嵌套。

Django对传统的MVC设计模式进行了修改,将视图分成View模块和Template模块两部分,将动态的逻辑处理与静态的页面展示分离开。而Model采用了ORM技术,将关系型数据库表抽象成面向对象的Python类,将数据库的表操作转换成Python的类操作,避免了编写复杂的SQL语句。

模型(Model):和MVC中的定义一样

模板(Template):将模型数据与HTML页面结合起来的引擎

视图(View):负责实际的业务逻辑实现

一张图表示:

首先我们先来看VIEWS

视图(View)是Django的MTV架构模式的V部分,主要负责处理用户请求和生成相应的响应内容,然后在页面或其他类型文档中显示。也可以理解为视图是MVC架构里面的C部分(控制器),主要处理功能和业务上的逻辑。

1. 第一个视图函数

在 Django 中,视图函数是一个 Python 函数或者类,开发者主要通过编写视图函数来实现业务逻辑。视图函数首先接受来自浏览器或者客户端的请求,并最终返回响应,视图函数返回的响应可以是 HTML 文件,也可以是 HTTP 协议中的重定向。接下来编写两个简单的视图函数:

from django.http import HttpResponse

def index(request):

return HttpResponse("Hello, World!")

def Hello_my_django(request):

return HttpResponse('

Hello my Django')

下面针对以上代码做个解析:

HttpResponse视图响应类型

从 django.http 模块中导入 HttpResponse,从它简单的名字我们可以得知,它是一种视图的响应类型。

视图函数参数request

我们定义了一个名为“Hello_my_django”的函数,Django 规定了,视图函数至少有一个参数,第一个参数必须是 request,request 是 HttpRequest 请求类型的对象,它携带了浏览器的请求信息,所以视图函数的第一个参数必须为 request。

return视图响应

视图函数要返回响应内容,这里的响应内容可以是字符串也可以是HTML,把它作为 HttpResponse 的对象返回给浏览器。

视图函数执行过程

上面视图函数的代码虽然区区几行,但是已经充分体现了视图层的实现过程。 Django 收到请求以后,首先创建一个带有请求信息的 HttpRequset 对象,将 HttpRequest 的对象 request 作为第一个参数传递给视图函数,视图接收参数后继续向下执行,然后选择加载对应的视图,最后返回 HttpResponse 对象给浏览器。

我们来写一个带参数的视图函数,顺带和上节的URLconf结合一下,也算复习一下url的编写配置

还是上一篇的例子,我们建一个图书网站

主url配置

from django.contrib import admin

from django.urls import path, include

urlpatterns = [

path('admin/', admin.site.urls),

path('book/', include('book.urls')),

]

book配置子路由

from django.urls import path

from . import views

urlpatterns = [

path('', views.index ,name='index'), #/book/

path('',views.book, name='book_id'), #/book/5

]

这里表示如果你请求访问 "/book/5/" ,Django 将会运行book()这个函数并且展并且传递参数5给这个函数。下面我们来写这个简单的函数

from django.http import HttpResponse

def book(request, book_id):

return HttpResponse("You're looking at book %s." % book_id)

这里我们输入127.0.0.1:8000/book/5就可以看到浏览器中的显示

好了 我们继续,上面我们写到HttpResponse函数需要返回一个html格式的文件,其实仍旧是返回的字符串类型,上面的例子

return HttpResponse('

Hello my Django')

如果你的html文件很长,需要逐渐增加怎么办呢?首先先说笨办法(只是告诉你可以这么做,并不符合实际开发,下面会讲如何返回模板)

response = HttpResponse()

response.write("

Here's the text of the Web page.

")

response.write("

Here's another paragraph.

")

然后我们来看看如何告诉浏览器,返回的是一个文件,或者说如何下载一个文件。

这里我们可以使用HttpResponse的content_type参数以及定义Content Disposition文件头

Content-disposition是MIME协议的扩展,MIME协议指示MIME用户代理如何显示附加的文件。当Internet Explorer接收到头时,他会激活文件下载对话框,它的文件名框自动填充headers指定的文件名。

#在urls.py输入

path('download.html', views.download)

#views.py代码

def download(request):

response = HttpResponse(content_type = 'text/csv)

response['Content-Disposition']='attachment; filename="downloadfile.csv"'

writer = csv.write(response)

writer.writerow(['A', 'B', 'C'])

return response

Django包含很多HttpResponse子类,用来处理不同的HTTP响应类型(见下标). 和HttpResponse一样, 这些子类在django.http中。class HttpResponseRedirect[source]:重定向,返回302状态码。已经被redirect()替代。

class HttpResponsePermanentRedirect[source]:永久重定向,返回301状态码。

class HttpResponseNotModified[source]:未修改页面,返回304状态码。

class HttpResponseBadRequest[source]:错误的请求,返回400状态码。

class HttpResponseNotFound[source]:页面不存在,返回404状态码。

class HttpResponseForbidden[source]:禁止访问,返回403状态码。

class HttpResponseNotAllowed[source]:禁止访问,返回405状态码。

class HttpResponseGone[source]:过期,返回405状态码。

class HttpResponseServerError[source]:服务器错误,返回500状态码。

返回Errors

在Django中返回HTTP错误码是很容易的。上面介绍了HttpResponseNotFound, HttpResponseForbidden, HttpResponseServerError等一些子类。View方法中返回这些子类的实例就OK了,例如:

def my_view(request):

# ...

if foo:

return HttpResponseNotFound('

Page not found

')

else:

return HttpResponse('

Page was found

')

当你返回错误,例如HttpResponseNotFound,你需要定义错误页面的 HTML 。

return HttpResponseNotFound('

Page not found

')

为方便起见,在你的网站里有个一致的 404 错误页面是个好办法,Django 提供 Http404 异常。如果你在视图的任何地方引发了 Http404 ,Django 会捕捉到它并且返回标准的错误页面,连同 HTTP 错误代码 404 。

用法示例:

from django.http import Http404

from django.shortcuts import render #关于render 马上说到,你可以先理解成HttpResponse但是可以返回模板

from .models import Book #这里牵扯到了model 我们先不管

# ...

def book(request, book_id):

try:

book = Book.objects.get(pk=book_id)

except Book.DoesNotExist:

raise Http404("Book does not exist")

return render(request, 'book/detail.html')

这里尝试用bject_or_404,下面是修改后的详情detail()视图代码:

from django.shortcuts import get_object_or_404, render

from .models import Book

# ...

def book(request, question_id):

book = get_object_or_404(Book, pk=book_id)

return render(request, 'book/detail.html')

为了在 Django 返回404时显示你自定义的 HTML,你可以创建名为404.html的HTML模板,并将其放置在你的模板树顶层。要注意的是这个模板将在DEBUG设为False时才生效。

render()

「载入模板,填充上下文,再返回由它生成的HttpResponse对象」是一个网站开发非常常用的操作流程。于是 Django 提供了一个快捷函数render

render(request,template_name,context=None,content_type=None,status=None,using=None)

官方定义:将给定的模板与给定的上下文字典组合在一起,并以渲染的文本返回一个HttpResponse对象。

其实就是接受传输的数据,再将其渲染到指定模板。

必选参数:

request用于生成此响应的请求对象。template_name要使用的模板的全名或模板名称的序列。如果给定一个序列,则将使用存在的第一个模板。

context:对HTML模板的变量赋值,以字典格式表示,默认情况下是一个空字典。

content_type:响应数据的数据格式,一般情况下使用默认值即可。

status:HTTP状态码,默认为200。

using:用于加载模板的模板引擎的 :setting:‘NAME’ 。

from django.shortcuts import render

def my_view(request):

# View code here...

return render(request, 'myapp/index.html', {

'foo': 'bar',

}, content_type='application/xhtml+xml')

redirect()

除了render函数外,还有redirect()函数。redirect()函数用于实现请求重定向,重定向的链接以字符串的形式表示,链接的地址信息可以支持相对路径和绝对路径,

redirect(to,*args,permanent=False,**kwargs)

permanent=True就是永久重定向

代码如下:

#urls.py中的url地址信息

path('login.html', views.login)

#views.py

def login(request):

return redirect('/') #相对路径,代表首页地址

#相对路径

#return redirect('http://127.0.0.1:8000/')

除了传递链接地址,还可以传递对象和视图

from django.shortcuts import redirect

def my_view(request):

...

obj = MyModel.objects.get(...)

return redirect(obj)

传递对象,对象的get_absolute_url()方法将被调用来指向重定向地址

def my_view(request):

...

return redirect('some-view-name', foo='bar')

传递视图名和一些可选的位置或关键字参数;URL 将使用reverse()方法来反向解析:

Request

我们知道当URLconf文件匹配到用户输入的路径后,会调用对应的view函数,并将 HttpRequest对象 作为第一个参数传入该函数。

我们来看一看这个HttpRequest对象有哪些属性和方法:属性说明实例

COOKIES返回一个包含了所有cookies的字典。键和值都是字符串data=request.COOKIES

FILES返回一个包含了所有的上传文件的 querydict 对象。通过表单所上传的所有 文件 都会保存在该属性中。  key的值是input标签中name属性的值,value的值是一个UploadedFile对象file=request.FILES

GET获取get请求的请求参数返回一个 querydict 对象(类似于字典,本文后面有querydict的介绍),该对象包含了所有的HTTP GET参数。

比如{"name":"Tom"},我们用request.GET.get('name'1的)可以得到"TOM"

POST获取get请求的请求参数返回一个 querydict 对象,该对象包含了所有的HTTP POST参数。通过表单上传的所有字符都会保存在该属性中(除了上传的文件,那个是FILES)。

META返回一个包含了所有http头部信息的字典request.META.get("REMOTE_ADDR")获取客户端的IP,这个下面详细讲一下

method获取该请求的方法,比如: GET POST .........if request.method == 'GET':

do_something()elif request.method == 'POST': do_something_else()

path所请求页面的完整路径(但不包括协议以及域名),也就是相对于网站根目录的路径。path=request.path

user中间件属性,表示当前登录的用户。name=request.user.username

if request.user.is_authenticated:

... # Do something for logged-in users.

else:

... # Do something for anonymous users.

META请求头信息

例:CONTENT_LENGTH 请求体当作一个字符串的总长度。

CONTENT_TYPE 请求体的MIME类型。

HTTP_ACCEPT 可以接受的内容类型的响应。

HTTP_ACCEPT_ENCODING 接受编码的响应。

HTTP_ACCEPT_LANGUAGE 接受语言的反应。

HTTP_HOST 客户端请求时用的服务端地址

HTTP_REFERER 参考页面

HTTP_USER_AGENT 客户端的标志信息

QUERY_STRING 一对一的查询字符串

REMOTE_ADDR 客户端IP

REMOTE_HOST 客户端主机名

REMOTE_USER 客服端的身份信息

REQUEST_METHOD 请求方式

SERVER_NAME 服务器主机名

SERVER_PORT 服务端开放的端口

更简单的获取头部信息的方式是我们使用request.headers,它比META少了content length以及content type信息

QueryDict

是一个类似于Python中字典的一种对象,他是Python中字典的子类,所以继承了字典的所有方法,当然QueryDict对字典的某些方法进行了加工,并补充了一些独特的方法。这里列出部分方法。详情请看: 官方文档 。

1 QueryDict.get(key,default=None) 返回key所对应的value,若key不存在,则返回default的值

2 QueryDict.update(other_dict) 更新

3 QueryDict.values() 列出所有的值

4 QueryDict.items() 列出所有的键值对,若一个key有多个值,只显示最后一个值。

5 QueryDict.pop(key) 删除某个键值对

6 QueryDict.getlist(key) 根据输入的key返回一个Python中的list

7 QueryDict.dict() 返回QueryDict的字典的表现形式

结合前面学的 我们来看一下一个很常见的登录函数怎么写,这里需要两个函数:authenticate(username,password)和login(request,user),位于django.contrib.auth模块中;

这两个方法需要结合使用,

1.authenticate(username,password)函数需要两个参数username,password,如果校验通过则返回User对象,如果校验不通过返回None,例如

from django.contrib.auth import authenticate

user = authenticate(username='john', password='secret')

if user is not None:

if user.is_active:

print "You provided a correct username and password!"

else:

print "Your account has been disabled!"

else:

print "Your username and password were incorrect."

login接受两个参数,第一个是request对象,第二个是user对象。login方法使用SessionMiddleware将userID存入session当中。注意,在用户还未登录的时候,也存在着匿名用户的Session,在其登陆之后,之前在匿名Session中保留的信息,都会保留下来。这两个方法要结合使用,而且必须要先调用authenticate(),因为该方法会User的一个属性上纪录该用户已经通过校验了,这个属性会被随后的login过程所使用,例如:

from django.contrib.auth import authenticate, login

def my_view(request):

username = request.POST['username']

password = request.POST['password']

user = authenticate(username=username, password=password)

if user is not None:

if user.is_active:

login(request, user)

# 跳转到成功页面.

else:

# 返回一个无效帐户的错误

else:

# 返回登录失败页面。

合在一起写一个例子

from django.contrib.auth import authenticate,login

#login登陆函数此处为了防止错乱,改为了login_

def login_(request):

if request.method=='POST':

user_name = request.POST.get("username",'')

pass_word = request.POST.get("password",'')

#authenticate方法用来验证用户的账号密码是否正确,如果正确,返回User对象,否则返回None

user = authenticate(username = user_name,password = pass_word)

if user is not None:#判断是否正确

login(request,user)#登陆账户

# 重定向到index主页

return redirect(index)#重定向到主页,切不可使用render方法,返回的是静态页面,css样式有问题。

else:

return render(request,'login.html',{'msg':'账号或密码错误!'})#返回页面提示错误

elif request.method=='GET':

return render(request,'login.html')

写到这里忽然发现后面的内容没法讲了,视图还会有三部分内容,一部分是从数据库中读取数据,这个牵扯到MODEL了,二部分是视图如何与模板结合,三部分是通用视图,所以这篇现在这里告一段落吧,下一节我们一起来看看MODEL以及ORM。

欢迎关注

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值