Django之视图

Posted yifchan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django之视图相关的知识,希望对你有一定的参考价值。

视图

视图的功能

接收请求,进行处理,与M和T进行交互,返回应答。
返回html内容 HttpResponse,也可能重定向 redirect,还可以返回json数据。

 

视图函数的使用

使用

1)定义视图函数
request参数必须有。是一个HttpRequest类型的对象。参数名可以变化,但最好不要更改。
2)配置url
建立url和视图函数之间的对应关系。

 

url配置的过程

  • 1)在项目的urls文件中包含具体应用的urls文件,在具体应用的urls文件中包含具体url和视图的对应关系。
  • 2)url配置项是定义在一个名叫urlpatterns的列表中,其中的每一个元素就是一个配置项,每一个配置项都调用url函数。

如下

test1000/url.py

urlpatterns = [
    url(r^admin/, admin.site.urls),
    url(r^, include(booktest.urls)),  # 包含booktest应用中的路由文件
]

booktest/url.py

urlpatterns = [
    url(r^index/, views.index),  # 显示图书信息
    url(r^create/, views.create),  # 添加一本书籍
    url(r^delete(\\d+)/, views.delete),  # 删除一本书籍
]

 

url匹配的过程

url匹配图解

技术图片

匹配示例:

url:http://127.0.0.1:8000/aindex?a=1

  • 1) 去除域名和后面的参数,剩下/aindex,再把前面的/去掉,剩下aindex
  • 2) 拿aindex先到项目的url.py文件中进行从上到下的匹配,匹配成功之后执行后面对应的处理动作,就是把匹配成功的部分a字符去除,然后拿剩下的部分index到应用的urls.py文件中再进行从上到下的匹配。
  • 3) 如果匹配成功则调用相应的视图产生内容返回给客户端。如果匹配失败则产生404错误。

 

错误视图

当我们在开发时,可以设置settings文件里面的DEBUG=True,但当我们要上线产品时,应该设置为False,否则会把网站的信息暴露出来。
开发时:

DEBUG = True
ALLOWED_HOSTS = []

要上线时:

DEBUG = True
ALLOWED_HOSTS = [*]

 

404: 找不到页面。可能原因

  • a)url没有配置
  • b)url配置错误
  • c)浏览器url’/’问题

500: 服务器端的错误。可能原因

  • a)视图出错

 

自定义404页面

修改为上线模式后,在templates下新建并编写一个404.html,即可。
在使用这个页面的过程中,Django会传过来一个模板变量, request_path ,表示用户请求路径。

500错误页面同理。

 

捕捉url参数

进行url匹配时,把所需要的捕获的部分设置成一个正则表达式组,这样django框架就会自动把匹配成功后相应组的内容作为参数传递给视图函数。
1)位置参数
位置参数,参数名可以随意指定


2)关键字参数:在位置参数的基础上给正则表达式组命名即可。
?P<组名>
关键字参数,视图中参数名必须和正则表达式组名一致.

 

捕获url参数示例:

url(r^delete(\\d+)/, views.delete),  # 捕获url参数:位置参数
url(r^delete(?P<bid>\\d+)/, views.delete),  # 捕获url参数:关键字参数

def delete(request, bid):
    """删除一本书籍"""
    # 1.获取书籍对象
    book = models.BookInfo.objects.get(id=bid)
    # 2.删除书籍
    book.delete()
    # 3.重定向
    return redirect(/index)

注意,使用关键字参数时,视图中的参数名应该和正则表达式中的参数名一致

 

普通登录案例

普通登录案例项目分析

1)显示出登录页面

  • a)设计url,通过浏览器访问 http://127.0.0.1:8000/login 时显示登录页面。
  • b)设计url对应的视图函数login。
  • c)编写模板文件login.html。
url 视图 模板文件
/login login login.html

 

2)登录校验功能

  • a)设计url,点击登录页的登录按钮发起请求http://127.0.0.1:8000/login_check时进行登录校验。
  • b)设计url对应的视图函数login_check。
  1. 接收表单提交过来的数据。
  2. 进行登录校验,若用户名密码正确则跳转到登录成功页。若失败在跳转到登录页面。
  • c)登录成功后跳转到首页。
url 视图 模板文件
/login_check login_check

 

普通登录示例代码 

定义login.html页面

技术图片
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Login</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<form action="/login_check/" method="post">
    <label for="username">用户:
        <input type="text" id="username" name="username">
    </label><br />

    <label for="password">密码:
        <input type="password" id="password" name="password">
    </label><br />
    
    <input type="submit" value="登录">
</form>

</body>
</html>
index.html

编写login函数

def login(request):
    """登录处理函数"""
    return render(request, "booktest/login.html")

配置login和login_check路由

url(r^login/$, views.login),
url(r‘^login_check/$‘, views.login_check),

编写login_check函数

def login_check(request):
    # 1.获取用户名和密码
    username = request.POST.get("username")
    password = request.POST.get("password")
    # 2.进行校验
    # 3.返回应答
    if username == "yifchan" and password == "yifchan":
        return redirect("/index")
    else:
        return HttpResponse("账号或密码错误")

 

 

HttpReqeust对象

服务器接收到http协议的请求后,会根据报文创建HttpRequest对象,这个对象不需要我们创建,直接使用服务器构造好的对象就可以。
视图的第一个参数必须是HttpRequest对象,即request,在django.http模块中定义了HttpRequest对象的API。

属性

下面除非特别说明,属性都是只读的。

path 一个字符串,表示请求的页面的完整路径,不包含域名和参数部分。
method 一个字符串,表示请求使用的HTTP方法,常用值包括:‘GET‘、‘POST‘。
在浏览器中给出地址发出请求采用get方式,如超链接。
在浏览器中点击表单的提交按钮发起请求,如果表单的method设置为post则为post请求。
encoding

一个字符串,表示提交的数据的编码方式。如果为None则表示使用浏览器的默认设置,一般为utf-8。

这个属性是可写的,可以通过修改它来修改访问表单数据使用的编码,接下来对属性的任何访问将使用新的encoding值。

GET QueryDict类型对象,类似于字典,包含get请求方式的所有参数。
POST QueryDict类型对象,类似于字典,包含post请求方式的所有参数。
FILES 一个类似于字典的对象,包含所有的上传文件。
COOKIES 一个标准的Python字典,包含所有的cookie,键和值都为字符串。
session 一个既可读又可写的类似于字典的对象,表示当前的会话,只有当Django 启用会话的支持时才可用,详细内容见"状态保持"。

 

QueryDict对象

  • 定义在django.http.QueryDict
  • HttpRequest对象的属性GET、POST都是QueryDict类型的对象
  • 与python字典不同,QueryDict类型的对象用来处理同一个键带有多个值的情况

方法get()

根据键获取值

如果一个键同时拥有多个值将获取最后一个值

如果键不存在则返回None值,可以设置默认值进行后续处理

dict.get(,默认值)
# 可简写为
dict[]

 

方法getlist()

根据键获取值,值以列表返回,可以获取指定键的所有值
如果键不存在则返回空列表[],可以设置默认值进行后续处理

dict.getlist(,默认值)

 

方法dict[‘键‘]

根据键获取值
和get()方法差不多,但没有值的时候会报错;

 

取QueryDict值示例

from django.http.request import QueryDict
q = QueryDict(a=1&b=2&c=3)
q[a]
q[b]
q.get(a)
q.get(c, default="")

应注意使用[]取值时如果没有值会报错,而get只会返回一个none,不会报错,所以一般使用get;

此外,QueryDict和字典的不同之处在于可以一个key对应多个value,但会取后面的那个value,
想要获取该key所有的value,可以通过dict.getlist(‘键‘,默认值)进行获取。

 

 

ajax请求

ajax,即异步的javascript。在不全部加载某一个页面部的情况下,对页面进行局的刷新,ajax请求都在后台。
图片,css文件,js文件都是静态文件。

技术图片

1)发起ajax请求:jquery发起
2)执行相应的视图函数,返回json内容
3)执行相应的回调函数。通过判断json内容,进行相应处理。

 

python和ajax结合使用

因为要引入jquery,一般对于这些静态文件,我们会创建static文件,将静态文件放入里面,在settings文件里面进行配置。

STATIC_URL = /static/
STATICFILES_DIRS = [os.path.join(BASE_DIR, static)] # 设置静态文件的保存目录

在static文件夹下新建js,css等文件;
在js中引入jquery文件;
编写ajax_test.html

技术图片
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <script src="/static/js/jquery-3.3.1.js"></script>
    <script>
        $(function () 
        #    绑定btnAjax的click事件#
            $(#btnAjax).click(function () 
                $.ajax(
                    url: /ajax_handle,
                    type: get,
                    datatype: json
                ).done(function (data) 
                    // 处理后端拿过来的数据
                    // console.log(data.res);
                    if (data.res == 1) 
                        $(#message).show().html("提示信息");
                    
                )
            )
        )
    </script>
    <style>
        #message display: none;color: red;
    </style>
</head>
<body>
<input type="button" id="btnAjax" value="ajax请求">
<div id="message"></div>
</body>
</html>
ajax_test.html

编写ajax_test函数

def ajax_test(request):
    """返回ajax页面"""
    return render(request, "booktest/ajax_test.html")

设计ajax_test,ajax_handle的url

url(r^ajax_test/$, views.ajax_test),
url(r‘^ajax_handle/$‘, views.ajax_handle),

编写ajax_handle处理函数

def ajax_handle(request):
    """ajax处理函数"""
    return JsonResponse("res": 1)

关于ajax调试,可以使用浏览器的network窗口,如果出现问题,就到network窗口,点击出错的请求,再点击response,就会有报错详情了;

 

ajax同步和异步

同步:等别人执行完再执行;
异步:不管别人有没有执行完,就执行;

ajax默认是异步的,即不等ajax请求返回数据,就执行ajax后面的代码,如果想要实现ajax通过不,可以添加‘async‘: false:

$.ajax(
    url: /ajax_handle,
    dataType: json,
    async: false, // 同步的ajax请求,默认为True
)

ajax默认是异步的请求

技术图片
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <script src="/static/js/jquery-3.3.1.js"></script>
    <script>
        $(function () 
            // 绑定btnAjax的click事件
            $(#btnAjax).click(function () 
                console.log("1");
                $.ajax(
                    url: /ajax_handle,
                    type: get,
                    datatype: json
                ).done(function (data) 
                    // 处理后端拿过来的数据
                    console.log("2");
                )
                console.log("3");
            )
        )
    </script>
    <style>
        #message display: none;color: red;
    </style>
</head>
<body>
<input type="button" id="btnAjax" value="ajax请求">
<div id="message"></div>
</body>
</html>
ajax异步示例代码

这个时候,是默认的异步ajax,就会依次弹出1,3,2;

 

同步的ajax请求,需要在ajax中添加 ‘async‘: false,

技术图片
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <script src="/static/js/jquery-3.3.1.js"></script>
    <script>
        $(function () 
            // 绑定btnAjax的click事件
            $(#btnAjax).click(function () 
                console.log("1");
                $.ajax(
                    url: /ajax_handle,
                    type: get,
                    datatype: json,
                    async: false, // 同步的ajax请求,默认为True
                ).done(function (data) 
                    // 处理后端拿过来的数据
                    console.log("2");
                )
                console.log("3");
            )
        )
    </script>
    <style>
        #message display: none;color: red;
    </style>
</head>
<body>
<input type="button" id="btnAjax" value="ajax请求">
<div id="message"></div>
</body>
</html>
ajax同步示例代码

这个时候,是同步的ajax,就会依次弹出1,2,3;

 

ajax登录案例

编写login_ajax.html页面

技术图片
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Login</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <script src="/static/js/jquery-3.3.1.js"></script>
    <script>
        $(function () 
            // 绑定btnLogin的click事件
            $(#btnLogin).click(function () 
                // 1.获取用户输入的用户名和密码
                $username = $(#username).val();
                $password = $(#password).val();
                // 2.携带用户名和密码,发起ajax请求,login_ajax_check
                $.ajax(
                    url: /login_ajax_check/,
                    type: post,
                    data: username: $username, password: $password,
                    datatype: json,
                ).done(function (data) 
                    // 登录成功,‘res‘: 1
                    // 登录失败,‘res‘: 0
                    if (data.res == 0) 
                        console.log("res0");
                        $(#error_message).show()
                    
                    else 
                        // 登录成功则跳转到首页
                        console.log("res1");
                        location.href = /index;
                    
                );
            )
        )
    </script>
    <style>
        #error_message 
            display: none;
            color: red;
        
    </style>
</head>
<body>

<div>
    <label for="username">用户:
        <input type="text" id="username" name="username">
    </label><br />

    <label for="password">密码:
        <input type="password" id="password" name="password">
    </label><br />
    <div id="error_message">账号名或密码错误</div>

    <input type="button" id="btnLogin" value="登录">
</div>

</body>
</html>
login_ajax.html

编写login_ajax函数

def login_ajax(request):
    """返回ajax登录页面"""
    return render(request, "booktest/login_ajax.html")

设计login_ajax路由:

url(r^login_ajax/$, views.login_ajax),

点击登录后ajax发送消息给后端路由,

编写login_ajax_check登录校验函数

def login_ajax_check(request):
    # 1.获取用户名和密码
    # 如果是ajax提交的,那么这里的get中的值应该和ajax发过来的值一样;
    username = request.POST.get("username")
    password = request.POST.get("password")
    # 2.进行校验
    # 3.返回应答
    if username == "yifchan" and password == "yifchan":
        return JsonResponse("res": 1)
    else:
        return JsonResponse("res": 0)

设计 login_ajax_check 路由:

url(r^login_ajax_check/$, views.login_ajax_check),

注意:ajax的请求在后台,不要返回页面或重定向,无效;比如当前端发登录的ajax给后端,后端校验用户名密码正确后,不能直接重定向到index页面,而是返回状态码,经过ajax判断状态码后重定向到index页面,即由前端重定向;

 

以上是关于Django之视图的主要内容,如果未能解决你的问题,请参考以下文章

django视图之分页

Django基础三之视图函数

Django之框架,视图,模板

Django之视图(views.py)

Django之views.py视图函数学习

人生苦短,我用python-- Day19 django框架之URL路由系统视图应用模板应用django之orm应用