(5) Django - 视图函数

2019-03-06  本文已影响0人  libdream

视图主要负责处理用户请求和生成相应的响应内容,然后在页面或其他类型文档中显示。具体流程是:

  1. 用户通过url发起请求。
  2. 项目根据URL信息将请求传递给相应的视图函数。
  3. 视图函数负责处理用户的请求,处理完成后,通过return返回数据内容给用户。
    return具有多种响应类型:
响应类型 说明
HttpResponse('Hello world') HTTP状态码200,将字符串‘Hello world’返回给用户
HttpResponseRedirect('/admin/') HTTP状态码302,重定向Admin站点的URL
HttpResponsePermanentRedirect('/admin/') HTTP状态码301,永久重定向Admin站点的URL(慎用)
HttpResponseBadRequest('BadRequest') HTTP状态码400,访问页面不存在或请求错误
HttpResponseNotFound('Not Found') HTTP状态码404,网页不存在或网页的URL失效
HttpResponseForbidden('Not Found') HTTP状态码403,没有访问权限
HttpResponseNotAllowed('NotAllowedGet') HTTP状态码405,不允许使用该请求方式
HttpResponseServerError('ServerError') HTTP状态码500,服务器内容错误

响应类型代表HTTP状态码,其核心作用是Web Server服务器用来告诉客户端当前的网页请求发生了什么事,或当前Web服务器的响应状态。


常用的return响应类型是HttpResponse()和HttpResponseRedirect(),但是Django对这两个功能做了封装,用更简洁的render()和redirect()函数来代替。

render()

render()的语法如下:

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

前两个参数是必需参数,其余参数是可选参数,说明如下:

如上文的带字典参数的URL的视图函数

from django.shortcuts import render
#带字典参数的URL的视图函数
def myyear_dict(request, year, month):
    return render(request, 'myyear_dict.html', context={'month':month}, status=500)

运行结果如下:


修改状态码500

redirect()

redirect()函数用于实现请求重定向,重定向的链接以字符串的形式表示,链接的地址信息可以支持相对路径和绝对路径。
例如把前文的首页index视图函数重定向到admin

from django.shortcuts import redirect
def index(request):
    #相对路径
    return redirect('/admin/')
    #绝对路径
    return redirect('http://127.0.0.1:8000/admin/')

这时候输入首页地址http://127.0.0.1:8000就会被重定向到Admin管理页面。

数据可视化

视图还可以与模型(Model)实现数据交互,即操作数据库。视图相当于一个处理中心,接收用户请求,根据请求信息读取并处理后台数据,最后生成HTML网页返回给用户。
举个例子,在index的models.py中编写以下代码:

from django.db import models

class Score(models.Model):
    id = models.IntegerField(primary_key=True)
    name = models.CharField(max_length=20)
    score = models.CharField(max_length=3)

通过以上代码,我们定义了一个Score的models,然后通过makemigrations和migrate命令就可以创建对应的数据表。

我们用SQLiteSpy软件打开数据库,通过sql语句,添加几条数据进去。


添加数据

完成添加数据后,我们在templates文件夹中新建一个模板文件index.html,输入以下代码:

<title>{{ title }}</title>
<ul>
    {% for result in name_list %}
    <li>{{ result.name }} --- {{ result.score }}</li>
    {% endfor %}
</ul>

这个模板中,我们将视图传递过来的变量title直接输出 ,循环遍历了name_list,输出了用户名和得分到列表中。
在views.py中我们将index视图函数重写:

#views.py中的index
from .models import Score

def index(request):
    name_list = Score.objects.values('name','score')
    context = {'title':'首页', 'name_list':name_list}
    return render(request, 'index.html', context=context)

首先导入models中的Score类,在index函数中,第一步读取数据库表Score中的name和score字段的所有数据,第二步构造要传递给模板文件的数据,最后将数据返回给模板文件index.html。运行结果如下:


image.png

获取请求信息

视图是用于接收并处理用户的请求信息的,请求信息存放在视图函数的参数request中,request的常用属性如下:

属性 说明 实例
COOKIES 获取客户端Cookie信息 data = request.COOKIES
FILES 字典对象,包含所有上载文件。该字典有三个键:filename文件名;content-type文件类型;content文件的原始内容 file=request.FILES
GET 获取GET请求的请求参数,以字典形式存储 request.GET.get('name')
POST 获取POST请求的请求参数,以字典形式存储 request.POST.get('name')
META 获取客户端的请求头信息,以字典形式存储 request.META.get('REMOTE_ADDR')
method 获取该请求的请求方式(GET或POST) data = request.method
path 获取当前请求的url地址 path = request.path
user 获取当前请求的用户信息 name = request.user.username

简单举个例子,在index 的urls.py中添加一个登录url信息,如下:

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

然后在视图views.py中添加视图函数login,如下:

def login(request):
    method = request.method
    name = request.GET.get('name')
    ip = request.META.get('REMOTE_ADDR')
    return HttpResponse(method + '---' + name + '---' + ip)

上面的代码中,分别获取了客户端请求的方法、GET请求的请求参数以及客户端的IP地址信息,在浏览器输入http://127.0.0.1:8000/login/?name=TOM ,运行结果如下:

image.png

可见请求方法是GET,获取到的GET参数name值为TOM,以及客户端的IP地址。

通用视图

通用视图是为了快速开发而出现的,Django的通用视图是通过定义和声明类的形式实现的,根据用途划分为三大类:

path('index/', views.ScoreView.as_view()),

可以看到,url信息里多了一个as_view()的方法,这是因为通用视图实质上是一个类,使用as_view()方法相当于对类进行实例化并由类方法as_view()还行处理。如果URL所指向的处理程序是由通用视图执行的,那么在编写URL时,URL所指向的处理程序应当是一个通用视图,并且该通用视图上必须使用as_view()方法。
然后,我们在views.py中编写通用视图ScoreView,代码如下:

from django.views import generic
class ScoreView(generic.ListView):
    #HTML模板名称
    template_name = 'index.html'
    #HTML模板里的变量名称
    context_object_name = 'name_list'
    #查询数据
    queryset = Score.objects.values('name','score')

    #重写get_queryset方法,查询数据库中的数据。
    # def get_queryset(self):
    #     name_list = Score.objects.values('name','score')
    #     return name_list

    #如果需要传递其他变量,则需要重写get_context_data()函数,并且需要上面的queryset变量
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['title'] = '首页'
        context['generic'] = '这是通用视图'
        return context

为了做对比,这里在index.html模板中增加了一个generic变量,程序运行结果如下:

通用视图

可以对比一下默认首页下的运行结果:


默认首页
上一篇 下一篇

猜你喜欢

热点阅读