Django教程 —— 视图及URL

2021-09-29 16:14:29 浏览数 (1)

引言

在 初步完善图书管理系统 中已经完成了后台管理的界面,但这一般是提供管理员来访问的。接下来就要做公共访问的页面了。当我们刚刚在浏览器中输入 http://127.0.0.1:8000/admin/ 之后,浏览器显示出了后台管理的登录页面,那有没有想过这个服务器是怎么给我们找到这个页面并返回呢?/admin/ 是我们想要请求的页面,服务器在收到这个请求之后,就一定对应着一个处理动作,这个处理动作就是帮我们产生页面内容并返回回来,这个过程在 Django 中是由 视图 来做的。

对于 Django 的设计框架 MVT ,用户在 URL 中请求的是 views 视图,视图接收请求后进行处理,并将处理的结果返回给请求者。

Django 中使用视图,一般需要进行两步操作:

  • 定义视图
  • 配置URL

运行环境

  • Python 3.9
  • Django 3.1.2

Django视图

基于函数的视图

视图函数的必须有一个参数,一般叫 request,视图必须返回 HttpResponse 对象,HttpResponse 中的参数内容会显示在浏览器的页面上。

定义视图函数

Django 项目中的应用下的 views.py 文件中定义如下格式函数即可

代码语言:javascript复制
# -*- coding:utf-8 -*-
"""
@Author   :Hui
@Desc     :{book应用视图模块}
"""
from django.http import HttpResponse


# /book
def index(request):
    """图书首页"""
    return HttpResponse("图书首页")
配置URL

查找视图的过程

请求者在浏览器地址栏中输入 URL ,请求到网站后,获取 URL 信息,然后与编写好的 URL配置 逐条匹配,如果匹配成功则调用对应的视图函数,如果所有的 URL配置都没有匹配成功,则返回 404 错误。

该如何配置呢?

我们只要在 Django 项目下的 urls.py 文件中添加自己 URL 匹配规则。

代码语言:javascript复制
# -*- coding:utf-8 -*-
"""
@Author   :Hui
@Desc     :{BMSTest項目的url匹配模块}
"""
from book import views
from django.urls import path
from django.contrib import admin


urlpatterns = [
    path('admin/', admin.site.urls),
    path('book', views.index),
]

urlpatterns url匹配列表中可以看见 path('admin/', admin.site.urls) 这行,这是 Django 项目默认

就有的匹配规则,代表访问 http://127.0.0.1:8000/admin/Django 会截取域名后面的地址进行匹配和处

理,截取后为 admin/,处理结果就是返回后台管理的登录页面。

path('book', views.index) 是我们自己加的匹配规则。意思就是当访问

http://127.0.0.1:8000/book 网址时, 截取后为 book , 然后在 urlpatterns 匹配列表中逐一匹配,

当匹配到 book 时符合匹配规则,让我们的 views.index 的视图函数进行处理。返回结果如下:

但我们一般把匹配规则定义成如下格式:

代码语言:javascript复制
# -*- coding:utf-8 -*-
"""
@Author   :Hui
@Desc     :{BMSTest項目的url匹配模块}
"""
from django.contrib import admin
from django.urls import path, re_path


urlpatterns = [
    re_path('admin/', admin.site.urls),		 # 后台管理
    re_path('^user/', include('user.urls')), # 用户模块
    re_path('^book/', include('book.urls')), # 图书模块
]

应在每个应用中创建 urls.py url配置文件,然后让项目包含其中 include('book.urls')

代码语言:javascript复制
# -*- coding:utf-8 -*-
"""
@Author   :Hui
@Desc     :{book应用的url匹配模块}
"""
from book import views
from django.urls import re_path


urlpatterns = [
    re_path('^index$', views.index),
]

但这次访问图书首页的网址就改成了 http://127.0.0.1:8000/book/index 。先拿 book/index 跟项目的 urls.py 进行匹对,开头匹配到了 book/ 然后就去 book.urls ,book应用下的 urls.py进行匹对。匹配到了 index 就返回图书首页。

注意^ 表示匹配开头,$ 表示匹配结尾。 path 不支持正则表达式,如需支持正则需要在 django.urls 导入 re_path 。如想学正则,推荐 Python玩转正则表达式,看完这篇你就会了,介绍了一些常用表达式,和在线生成正则工具网站。

基于类的视图

基于类的视图提供了一种将视图实现为Python对象而非函数的替代方法。它们不能替代基于功能的视图,但是与基于功能的视图相比具有某些区别和优势:

  • 与特定HTTP方法(GET,POST等)相关的代码组织可以通过单独的方法而不是条件分支来解决。
  • 诸如 mixin(多重继承)之类的面向对象技术可用于将代码分解为可重用的组件。
定义类视图

还是在 Django 项目中的应用下的 views.py 文件中定义

首先导入 Django 的视图类

代码语言:javascript复制
from django.views.generic import View

然后让我们自己写的类继承 Django 的类视图 View

从本质上讲,基于类的视图使您可以使用不同的类实例方法来响应不同的 HTTP 请求方法,而不是使用单个视图函数中的有条件分支代码。

因此,视图函数中用于处理 HTTP请求的代码如下所示:

代码语言:javascript复制
# -*- coding:utf-8 -*-
"""
@Author   :Hui
@Desc     :{book应用视图模块}
"""
from django.http import HttpResponse


# /book/index
def index(request):
    """图书首页"""
    if request.method == "GET":
        # 视图逻辑
        # ...
        return HttpResponse("GET请求 - 图书首页")

    elif request.method == "POST":
        # 视图逻辑
        # ...
        return HttpResponse("POST请求 - 图书首页")

在基于类的视图中,这将变为:

代码语言:javascript复制
# -*- coding:utf-8 -*-
"""
@Author   :Hui
@Desc     :{book应用视图模块}
"""
from django.views import View
from django.http import HttpResponse


# /book/info
class InfoView(View):
    """图书信息视图类"""

    def get(self, request):
        # 视图逻辑
        # ...
        return HttpResponse("GET请求 - 图书信息页")
    
    def post(self, request):
        # 视图逻辑
        # ...
        return HttpResponse("POST请求 - 图书信息页")
配置URL

因为 DjangoURL解析器 希望将请求和关联的参数发送给可调用的函数而不是类,所以基于类的视图具有一个

as_view() 的类方法,该类方法返回一个函数,该请求可以在请求到达与关联模式匹配的 URL 时被调用。该

函数创建该类的实例,调用 setup() 以初始化其属性,然后调用其 dispatch() 方法。 dispatch 查看该请求

以确定它是否为 GET, POST 等,并将请求转发给匹配的方法(如果已定义),否则将其引发HttpResponseNotAllowed

因此我么配置URL是只要 类视图.as_view()即可,例如:

代码语言:javascript复制
# -*- coding:utf-8 -*-
"""
@Author   :Hui
@Desc     :{book应用的url匹配模块}
"""
from book import views
from django.urls import re_path
from book.views import InfoView


urlpatterns = [
    re_path('^index$', views.index),
    re_path('^info$', InfoView.as_view())
]

当在浏览器访问 http://127.0.0.1:8000/book/info 网址时, 截取后为 book/info , 然后在 urlpatterns 匹配列表中逐一匹配,当匹配到 ^info$ 时符合匹配规则,让我们的 InfoView.as_view() 的类视图进行处理。返回结果如下:

公众号

新建文件夹X

大自然用数百亿年创造出我们现实世界,而程序员用几百年创造出一个完全不同的虚拟世界。我们用键盘敲出一砖一瓦,用大脑构建一切。人们把1000视为权威,我们反其道行之,捍卫1024的地位。我们不是键盘侠,我们只是平凡世界中不凡的缔造者 。

0 人点赞