Django2.0入门教程:视图函数


通过请求与响应MVC与MTV开发模式 这两篇文章,我们明白了,Django请求的生命周期:通过URL对应关系匹配 ->找到对应的函数(或者类)->返回字符串(或者读取Html之后返回渲染的字符串)。这里RUL对应的函数,我们就叫视图函数。

视图函数是一个简单的Python 函数,它接受Web请求并且返回Web响应。响应可以是一张网页的HTML内容,一个重定向,一个404错误,一个XML文档,或者一张图片. . . 是任何东西都可以。无论视图本身包含什么逻辑,都要返回响应。这个视图函数代码一般约定是放置在项目或应用程序目录中的名为views.py的文件中。

http请求中产生两个核心对象:

1、http请求---->HttpRequest对象,用户请求相关的所有信息(对象)

2、http响应---->HttpResponse对象,响应字符串

例子:

新建views1.py
from django.http import HttpResponse
def index(request):
    return HttpResponse("你好")
 
在urls.py中修改配置
from . import views1
path('', views1.index, name='index'),

例子里,我们用到的request,就是HttpRequest对象。HttpResponse("你好"),就是HttpResponse对象,它向http请求响应了一段字符串。

视图函数,就是围绕着HttpRequest和HttpResponse这两个对象进行的。

一、HttpRequest对象,request请求信息和属性和方法。

属性和方法包含下面几个:

1、request.path:这个主要是用来获取访问文件路径

from django.shortcuts import render,HttpResponse
def index(request):
    print(request.path)
    print(request.get_full_path())
    return render(request,'index.html')

如果我们是通过http://127.0.0.1:8000/post/23?page=1请求的话。

request.path的结果为:/post/23

request.get_full_path()的结果为:/post/23?page=1

2、request.method属性:获取请求中使用的HTTP方式(POST/GET)

from django.shortcuts import render,HttpResponse
def index(request):
    print(request.method)
    return render(request,'index.html')

3、request.body属性:含所有请求体信息 是bytes类型

4、request.GET,获取HTTP GET方式请求传参,的参数(字典类型)

from django.shortcuts import render,HttpResponse
def index(request):
    print(request.GET)
    return render(request,'index.html')

如果我们通过http://127.0.0.1:8000/post/?fenlei=123 & page=3 请求。

获取到:<QueryDict: {' page': ['456'], 'fenlei': ['123 ']}>

5、request.POST,获取POST请求的数据(类字典对象) 请求体里拿值。服务器收到空的POST请求的情况也是可能发生的,也就是说,表单form通过服务器收到空的POST请求的情况也是可能发生的,也就是说,表单form通过if request.POST来判断是否使用了HTTP POST 方法;应该使用  if request.method=="POST"。

6、request.COOKIES,包含所有cookies的标准Python字典对象;keys和values都是字符串。

7、request.FILES,包含所有上传文件的类字典对象;FILES中的每一个Key都是<input type="file" name="" />标签中name属性的值,FILES中的每一个value同时也是一个标准的python字典对象,包含下面三个Keys:filename:上传文件名,用字符串表示、content_type:上传文件的Content Type、content:上传文件的原始内容。

8、request.user,是一个django.contrib.auth.models.User对象,代表当前登陆的用户。如果访问用户当前没有登陆,user将被初始化为django.contrib.auth.models.AnonymousUser的实例。你可以通过user的is_authenticated()方法来辨别用户是否登陆:if request.user.is_authenticated();只有激活Django中的AuthenticationMiddleware时该属性才可用。

9、request.session,唯一可读写的属性,代表当前会话的字典对象;自己有激活Django中的session支持时该属性才可用

10、request.GET.get('name'),拿到GET请求里name的值,如果某个键对应有多个值,则不能直接用get取值,需要用getlist,如:request.POST.getlist("hobby")。

二、HttpResponse响应对象方法和属性。

对于HttpRequest请求对象来说,是由django自动创建的,但是,HttpResponse响应对象就必须我们自己创建。每个view请求处理方法必须返回一个HttpResponse响应对象。HttpResponse类在django.http.HttpResponse。

HttpResponse对象的常用方法:

1、render函数。将指定页面渲染后返回给浏览器。

render(request, template_name[, context])

结合一个给定的模板和一个给定的上下文字典,并返回一个渲染后的HttpResponse对象。

def index(request):
    blog_index = models.Article.objects.all().order_by('-id')
    print(request.body)
    context = {
        'blog_index':blog_index,
    }
    return render(request, 'index.html',context)

参数:

request: 用于生成响应的请求对象。

template_name:要使用的模板的完整名称,可选的参数

context:添加到模板上下文的一个字典。默认是一个空字典。如果字典中的某个值是可调用的,视图将在渲染模板之前调用它。

content_type:生成的文档要使用的MIME类型。默认为DEFAULT_CONTENT_TYPE 设置的值。

status:响应的状态码。默认为200。

render方法主要是将从服务器提取的数据,填充到模板中,然后将渲染后的html静态文件返回给浏览器。这里一定要注意:render渲染的是模板。

结合我们MVC与MTV开发模式里博客开发的例子,我们的模板是这样写的:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>博客首页</title>
</head>
<body>
<div style="margin: 0 auto">
    <ul>
    <h3>最新文章</h3>
        {% for x in blog_index %}
        <li>{{ x.title }}</li>
        {% endfor %}
    </ul>
</div>
</body>
</html>

上面 {% for x in blog_index %}到{% endfor %}之间包括的就是我们要从数据库取出的数据,进行填充。对于这样一个没有填充数据的html文件,浏览器是不能进行渲染的,所以,对于上述{% for x in blog_index %}到{% endfor %}之间的内容先要被render进行渲染之后,才能发送给浏览器。

Views里是这样写的:

def index(request):
    blog_index = models.Article.objects.all().order_by('-id')#从数据库中取出文章数据
    print(request.body)
    context = {
        'blog_index':blog_index,#将数据保存在blog_index
    }
    return render(request, 'index.html',context)#通过render进行模板渲染

2、redirect函数,多用于页面跳转。

redirect的参数可以是:

一个模型:将调用模型的get_absolute_url() 函数

一个视图,可以带有参数:将使用urlresolvers.reverse 来反向解析名称

一个绝对的或相对的URL,将原封不动的作为重定向的位置。

默认返回一个临时的重定向;传递permanent=True 可以返回一个永久的重定向。

示例:

传递一个对象,将调用get_absolute_url() 方法来获取重定向的URL:

from django.shortcuts import redirect
def my_view(request):
    ...
    object = MyModel.objects.get(...)
    return redirect(object)

传递一个视图的名称,可以带有位置参数和关键字参数;将使用reverse() 方法反向解析URL:

def my_view(request):
    ...
    return redirect('some-view-name', foo='bar')

传递要重定向的一个硬编码的URL:

def my_view(request):
    ...
    return redirect('/some/url/')

也可以是一个完整的URL:

def my_view(request):
    ...
    return redirect('https://www.django.cn/')

默认情况下,redirect() 返回一个临时重定向。以上所有的形式都接收一个permanent 参数;如果设置为True,将返回一个永久的重定向:

def my_view(request):
    ...
    object = MyModel.objects.get(...)
    return redirect(object, permanent=True)

render和redirect两者区别:    

第一,假如render返回一个登陆成功后的页面,刷新该页面将回复到跳转前页面。而redirect则不会

第二,如果页面需要模板语言渲染,需要的将数据库的数据加载到html,那么render方法则不会显示这一部分,render返回一个登陆成功页面,不会经过url路由分发系统,也就是说,不会执行跳转后url的视图函数。这样,返回的页面渲染不成功;而redirect是跳转到指定页面,当登陆成功后,会在url路由系统进行匹配,如果有存在的映射函数,就会执行对应的映射函数。