[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, reversedef 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, reversedef index(request):# 因为重定向的路由myvariable需要接收3个参数 year month dayargs = [\'2020\', \'11\', \'05\']# 转成 url路由url = reverse(\'index:myvariable\', args=args)print(url)# permanent 设置永久重定向301,默认是false 302return 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 ConfigurationThe `urlpatterns` list routes URLs to views. For more information please see:https://docs.djangoproject.com/en/2.2/topics/http/urls/Examples:Function views1. Add an import: from my_app import views2. Add a URL to urlpatterns: path(\'\', views.home, name=\'home\')Class-based views1. Add an import: from other_app.views import Home2. Add a URL to urlpatterns: path(\'\', Home.as_view(), name=\'home\')Including another URLconf1. Import the include() function: from django.urls import include, path2. 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# 配置媒体文件夹mediafrom django.views.static import servefrom 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)# 500def 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 效果如下