您的位置:首页 > 编程语言 > Go语言

《Django Web应用开发实战》学习笔记 8- 视图函数(FBV视图),render,redirect,自定义404|500 页面

2020-11-06 23:20 1096 查看

[toc]

学习资料

《Django Web应用开发实战》

1. 视图

Django中的视图(Views)是MTV架构模式中的v,处理用户请求和生成相应的响应内容并显示在页面,django中分为视图函数 (def),视图类(class),这> 里用FBV视图(视图函数)引出常用方法

2. 响应类

http协议分为5种状态:

消息:1开头的状态码

成功:2开头的状态码,常用的200

重定向:3开头的状态码,常用302

请求错误:4开头的状态码,常用404

服务器错误:5开头的状态码,常用502

可以使用Django的内置响应类,来设置不同的响应方式

响应类型 说明
HttpResponse('hello world') 状态码200,请求已成功被服务器接收
HttpResponseRedirect('/') 重定向根路由 302
HttpResponseNotFound() 网页不存在/网页的url失效 状态码404
HttpResponseForbidden() 状态码403 没有访问权限
HttpResponseServerError() 状态码500, 服务器内容错误
JsonResponse({"name": "xiaojun"}) 默认状态码200,响应内容为Json数据

其他的还有很多,但目前我觉得这些够用了

3. 返回响应内容

学习过前面的内容我们大概都记住了在视图函数中我们使用过

retrun render(request, 'index.html')
这段代码,下面介绍render函数的作用

  • 为了解决HttpResponse传输网页内容过多时,需要大量的视图函数代码量,以及体现模板的作用,Django在此之上封装,定义了render()函数
  • render:参数 request: 必要参数,浏览器向服务器发送的请求对象,包含用户信息,请求方式,请求内容等
  • template_html:必须参数,模板文件名,生成网页内容
  • context:对模板上下文(模板中的变量)赋值,以字典格式传递,默认情况下是个空字典
  • content_type:响应内容的数据格式,一般都用默认值
  • status:响应状态码,默认200
  • using:设置模板引擎,用于解析模板文件

first_app/views.py
里面的
index
视图函数修改如下

...
from django.urls import resolve, reverse

def index(request):

# 意为访问这个函数返回 index.html的文件内容
# 函数执行完后必须使用return返回处理结果
# return render(request, 'index.html')

# 访问与index视图函数绑定的路由,将重定向到
# return redirect(reverse('index:trunTo'))

value = {'title': 'this is title.'}
# 1. 当视图传递变量过多时,设置context就比较繁琐了
# return render(request, template_name='index.html', context={'value': value})
# 2. 使用 python 内置函数 locals():返回包含当前作用域的局部变量的字典。
print(locals())  # {'request': <WSGIRequest: GET '/index/'>, 'value': {'title': 'this is title.'}}
return render(request, template_name='index.html', context=locals())
...

将项目目录下的

templates/index.html
修改如下

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hello World</title>
</head>
<body>
<span>接收过来的value: {{ value }}</span>
<br>
<span>接收过来的value.title: {{ value.title }}</span>
<br>
<br>
<!--- 此为模板语法
用来生成路由地址,下面模板语法url 的4个参数
myvariable: 命名为myvariable的路由
2019: 代表路由地址变量year
... 关于路由地址变量与模板语法url 如果有参数 需要对应参数个数 不同的参数值用空格隔开
---->
{#    <a href="{% url 'myvariable' '2020' '11' '05' %}">查看日期</a>#}
{#    此为模板语法的注释: 下面使用路由空间:路由命名来实现 模板语法url生成路由地址, 需要注意如果路由定义了路由空间必须使用哦#}
<a href="{% url 'index:myvariable' '2020' '11' '05' %}">查看日期</a>
</body>
</html>

访问

http://127.0.0.1:8000/index/
效果如下

4. 设置重定向

之前的代码里使用了redirect来实现重定向,其实它的本质是封装了HttpResponseRedirect和HttpResponsePermanentRedirect-永久重定向函数

修改first_app/views.py下

index
视图函数如下

from django.http import *
from django.shortcuts import render, redirect

# Create your views here.
# 视图函数index必须设置一个参数,通常命名为request-代表当前用户的请求对象,该对象里面包含当前请求方式,用户,内容等信息
from django.urls import resolve, reverse

def index(request):
# 因为重定向的路由myvariable需要接收3个参数 year month day
args = ['2020', '11', '05']
# 转成 url路由
url = reverse('index:myvariable', args=args)
print(url)
# permanent 设置永久重定向301,默认是false 302
return redirect(url, permanent=True)
# 设置重定向302
# return HttpResponseRedirect(url)
# # 设置重定向301
# return HttpResponsePermanentRedirect(url)

def myvariable(request, year, month, day):
# year, month, day 来自路由请求地址设置的变量
# 通过debug发现,month传递过来的数据时int类型的
args = ['2020', '11', '05']
# 先使用reverse,生成路由地址, 用args将使用列表传递路由地址参数 不能与kwargs一起使用
# 使用kwargs 用字典传递地址参数
kwargs = {
'year': year,
'month': month,
'day': day
}
# index:myvariable -- 命名空间:路由命名, 如果只有路由命名 就只写路由命名
url_path = reverse('index:myvariable', kwargs=kwargs)
print(url_path, type(url_path))  # /2020/11/05 <class 'str'>
# 再使用resolve, 转成ResolverMath对象, 参数path, 路由地址
result = resolve(url_path)
"""
ResolverMatch(func=first_app.views.myvariable, args=(), kwargs={'year': '2020', 'month': 11, 'day': '05'},
url_name=myvariable, app_names=['first_app'], namespaces=['index'], route=<str:year>/<int:month>/<slug:day>)
<class 'django.urls.resolvers.ResolverMatch'>
"""
print(result, type(result))

return HttpResponse(year + '/' + str(month) + '/' + str(day))

5. 异常响应

异常响应:404和500的响应状态,通过render函数设置status参数的状态码就可实现

1. 在FirstDajngo/urls.py修改如下

"""FirstDjango URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/2.2/topics/http/urls/
Examples:
Function views
1. Add an import:  from my_app import views
2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
1. Add an import:  from other_app.views import Home
2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
# 导入内置的admin 模块
from django.contrib import admin
# 导入Django路由函数模块,
from django.urls import path, re_path, include

# 配置媒体文件夹media
from django.views.static import serve
from django.conf import settings

# 代表整个项目的路由集合
urlpatterns = [
# path 设定admin的路由信息
path('admin/', admin.site.urls),
# include('first_app.urls') 这个路由地址将统一管理first_app下的路由,first_app里面的路由= ''+first_app路由地址
# 如果first_app 有个路由地址是index 则最终访问为 ''+'index/' = IP:8000/index/
# path('', include('first_app.urls')),    # 路由地址为/即 127.0.0.1:8000 include是将该路由信息分发给first_app的urls.py处理

# 使用命名空间
path('', include(('first_app.urls', 'first_app'), namespace='index')),
# 配置媒体文件的路由地址
re_path('media/(?P<path>.*)', serve, {'document_root': settings.MEDIA_ROOT}, name='media'),

# 指向user应用的urls.py, include需要使用namespace(命名空间时), 第一个参数必须以元组形式传递(应用名.urls, 应用名),且元组长度为2
# Django的命名空间可以为我们快速定位到某个项目的urls.py再结合路由命名能快速的定位到具体的路由的具体信息,以得到有效的管理路由列表
path('user/', include(('user.urls', 'user'), namespace='user')),
]

# 当响应状态码出现404/500时将调用对应的视图函数
# 全局404 页面配置
handler404 = "first_app.views.page_not_found"
# 全局 500 页面配置
handler500 = 'first_app.views.page_error'

2.

first_app/views.py
添加下面两个视图函数

# 404视图
def page_not_found(request, exception):
return render(request, '404.html', status=404)

# 500
def page_error(request):
return render(request, '500.html', status=500)

3. 在项目目录下tmmplates下添加404.html 和 500.html

tmmplates/404.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>404页面</title>
</head>
<body>
<h3>404 页面</h3>
</body>
</html>

tmmplates/500.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>500页面</title>
</head>
<body>
<h3>500 页面</h3>
</body>
</html>

4. FirstDjango/settings.py修改两个位置如下

...
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = False

# 允许访问列表,当DEBUG为True时允许127.0.0.1/localhost访问, 允许所有IP访问设置['*']
ALLOWED_HOSTS = ['*']
...

访问:http://127.0.0.1:8000/2020/11/05/123 效果如下

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: