Python后台开发(第一章: 路由与模板)
1 Web原理介绍
Django可以更快地构建更好的Web应用程序并减少代码。
Django官方网址:https://www.djangoproject.com/
2 Django环境搭建和入门案例
2.1 环境搭建
代码部分:
pip install django==2.2
pip install pillow
2.2 环境搭建步骤
2.2.1 创建项目
2.2.1.1第一种方式
注:
- 使用的Pycharm必须是专业版(社区版有很多功能不支持,例如数据库可视化)
- 选择Python环境解释器在第一周环境搭建中有讲述
2.2.1.2 第二种方法
从命令行cd到您要存储代码的目录,然后运行以下命令:
django-admin startproject myweb
注:
使用上述命令需要将django的bin目录添加到环境变量中,如:C:\Users\admin\AppData\Roaming\Python\Python36\site-packages\django\bin
2.2.2 项目结构
- manage.py:一个命令行实用程序,可以让您以各种方式与此Django项目进行交互。你可以阅读所有的细节
manage.py在Django的管理和manage.py - web_1入门案例/目录是您的项目的实际Python包。它的名字是您需要用来导入其中的任何内容的Python包名称(例如myweb.urls)。
- web_1入门案例/init.py:一个空的文件,告诉Python这个目录应该被认为是一个Python包。
- web_1入门案例/settings.py:此Django项目的设置/配置。Django设置会告诉你所有关于设置的工作原理。
- web_1入门案例/urls.py:该Django项目的URL声明;您的Django动力网站的“目录”。
- web_1入门案例/wsgi.py:WSGI兼容的Web服务器为您的项目提供服务的入口点。
2.2.3 创建app
要创建您的应用程序,请确保您与目录位于同一目录,manage.py 并键入以下命令:
python manage.py startapp myapp
注:若当前环境中有两个python环境,可使用python3或python3命令来调用3的环境,如:
python3 manage.py startapp myapp
2.2.4 加载app
在settings的INSTALLED_APPS中加载创建的新应用:
注:
- 添加的时候注意格式 ,后边一定要跟上逗号,保持列表的格式.
- 2种添加的方式,效果相同,使用任意一种即可.
2.2.5 运行服务器
运行以下命令:
要创建您的应用程序,请确保您与目录位于同一目录,manage.py 并键入以下命令:
python manage.py runserver`
注:若当前环境中有两个python环境,可使用python3或python3.6命令来调用3.6的环境,如
python3 manage.py runserver
默认情况下,该runserver命令在端口8000的内部IP上启动开发服务器。当然也可以指定端口开启服务,如8080端口:
python manage.py runserver 8080
如果要更改服务器的IP,请将其与端口一起传递。例如:
python manage.py runserver 0.0.0.0:8000
2.2.6 简单demo的实现
- 我们来写第一个视图。打开文件myapp/views.py 并放入以下Python代码:
from django.http import HttpResponse
def index(request):
return HttpResponse("Hello, world. You're at the myapp index.")
- 这是Django中最简单的视图。要调用视图,我们需要将其映射到一个路由,要在myapp目录中创建一个名为urls.py。应用目录应该如下所示
这是Django中最简单的视图。要调用视图,我们需要将其映射到一个路由,要在myapp目录中创建一个名为urls.py。应用目录应该如下所示
- 在myapp/urls.py文件中包含以下代码:
from django.urls import path
from . import views
urlpatterns = [
path(r'', views.index, name='index'),
]
- 下一步是将主路由文件代码指向myapp.urls模块。 在myweb/urls.py添加一条导入文件从 django.urls里面导入path()和include()这两个方法
from django.contrib import admin
from django.urls import path,include
urlpatterns = [
path(r'\^admin/', admin.site.urls),
path(r'\^myapp/', include('myapp.urls')),
]
注:
- 其中include()函数允许引用其他的子路由文件,请注意,该include()函数的正则表达式没有$(字符串匹配字符),而是尾部的斜杠。 每当Django遇到时include(),它会排除与该点匹配的任何部分,并将剩余的字符串发送到子路由进行进一步处理。
- include()使即插即用的URL变得容易。只要在传递参数为 myapp.urls 即可
- include()可以一直使用, admin.site.urls是唯一的例外。
- 现在已将index视图连接到URLconf中。让它验证它的工作,运行以下命令:
python manage.py runserve
3 基本路由映射与命名空间
3.1 基本路由映射
3.1.1 概念
就像Django所支撑网站的目录。它的本质是URL与要为该URL调用的视图函数之间的映射表;你就是以这种方式告诉Django,对于这个URL调用这段代码,对于那个URL调用那段代码。
3.1.2 主路由与子路由的映射配置实例
3.2 处理器命名
3.2.1 概念
处理器命名即定义url的name值,就是给该url起的别名,在视图文件和前端模板中可以使用 name值进行快捷调用.
3.2.2 基础格式
myapp中的urls.py中:
from django.urls import path
from .import views
urlpattern=[
path('',views.index_handler,name='index')
]
3.2.3 命名实例
3.2.4 调用实例
3.3 命名空间
3.3.1 概念
命名空间的作用是,当一个项目中存在多个应用时,为了防止处理器的name值冲突,所以引入了命名空间的使用.
3.3.2 原理图
3.3.3 基本格式
path('user/',include(('[urls.py的地址]','[app的名字]'),namespace='[命名空间]'))
3.3.4 实例
path('user/',include(('myapp.urls','myapp'),namespace='user'))
注: 加入命名空间后 ,在视图和模板层快捷调用处理器name值时,调用方式为:
namespace: name.
如下图:
4 正则路由映射参数的传递和接收
4.1 manage.py启动项目
- 打开manage.py文件,CTRL+SHIFT+F10快捷键启动manage.py文件
- 点击Edit Configurations,
- 在Parameters的输入框输入:runserver 8000
如下图:
- 切换到manage.py文件,CTRL+SHIFT+F10启动服务
4.2 正则参数传递与接收
4.2.1 path和re_path
- 函数path()具有四个参数,两个必须参数:route 和 view,两个可选参数:kwargs 和name。即路由和视图是必填参数,
- rout 参数:route 是一个匹配URL的准则。准则不会匹配GET和POST域名和参数。例如,处理请求https://www.baidu.com/image/时,尝试匹配image/处理请求https://www.example.com/myapp/?page=3时,也只会尝试匹配 myapp/。
- view参数:当 Django找到了一个匹配的准则,就会调用这个特定的视图函数,并传入一个HttpRequest对象作为第一个参数,被“捕获”的参数以关键字参数的形式传入。
- kwargs:任意个关键字参数可以作为一个字典传递给目标视图函数。
- name:为你的URL取名能使你在 Django 的任意地方唯一地引用它,尤其是在模板中
- 注:re_path和path的作用都是一样的。只不过re_path是在写url的时候可以用正则表达式,功能更加强大,如果用到正则表达式,则必须使用
re_path
4.2.2 django-path函数源码
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FCkyJHpx-1575277751579)(image/2aae16fa3ddbc073c7931f5a552df25f.png)]
4.2.3 使用实例
- 导入re_path与re_path的使用:
- 处理器接收:
- 正则表达式
表达式 | 说明 |
---|---|
. | 除了\n和\r的所有字符 |
\d | 数字 |
\D | 非数字 |
\w | 数字字母和下划线 |
\W | 非数字字母和下划线 |
\s | 空格(包括制表符、换页符等) |
* | 出现次数>=0 + 出现次数>=1 |
{n} | 出现次数=n |
{n,m} | m >= 出现次数 >= n |
^ | 以开头 |
$ | 以结尾 |
5 反向解析处理器
5.1 导包方式
from django.shortcuts import reverse
5.2 有参,无参处理器的使用方法
5.2.1 无参
格式: reverse('[命名]') 实例: reverse("user:index")
5.2.2 有参
格式: reverse('[命名]',args=(传递参数1, [传递参数2]... ...)
实例: reverse("user:re",args=("123",))
5.3 代码实例
- 配置视图文件.
- 配置url.py:
- 运行测试
- 在反向解析的过程之中 可能碰到下面的错误信息:
gbk' codec can't decode byte 0xa6 in position 9737: illegal multibytesequence
参考链接: https://blog.csdn.net/yixiaotian1993/article/details/89190213
6 Request对象与Response对象
6.1 Request和Response
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pVWiLx2x-1575277751584)(image/21a600dec791767728abc849bd2ab4c9.png)]
Django服务器收到请求后,会自动创建一个Request对象,匹配URLconf中对应的view方法,并将这个Request对象作为第一个参数传递给view方法。而view方法会经过一系列操作之后,返回一个Response对象,返回给客户端
6.2 Request对象
6.2.1 概念
Django中的Request对象本质是HttpRequest,django将请求报文中的请求行、首部信息、内容主体封装成HttpRequest类中的属性,当URLconf文件匹配到用户输入的路径后,会调用对应的view函数,并将 HttpRequest对象 作为第一个参数传入该函数.
6.2.2 构成参数
关键字 | 说明 |
---|---|
method | 返回请求的方式(GET|POST) |
path | 返回页面的路径(不包括域名) |
META | 封装请求头的数据 (REMOTE_ADDR:客户端的IP地址 CONTENT_TYPE:请求正文的MIME类型) |
GET | 封装GET请求数据的QueryDict对象 |
POST | 封装POST请求数据的QueryDict对象 |
FILES | 封装上传文件数据 |
COOKIES | 封装请求的cookies,类似字典的对象 |
session | 可以读写的类似字典的对象 |
注:
- GET会把数据放在url中,在url中可以显示出传递的数据格式和内容
- POST会把数据加密封装在header中,在url请求中不会携带数据.
6.2.3 代码实例
- views.py文件
- 测试运行
6.3 Response对象
6.3.1 HttpResponse
6.3.1.1 概念
HttpResponse对象由我们手动创建,我们设计的每一个视图都需要实例化,填充和返回一个HttpResponse,也就是函数的return的值。
6.3.1.2 基础格式
HttpResponse( content="【响应体】", content_type="【MIME类型】", status="【状态码】" ) |
---|
6.3.1.3 MIME类型
MIME类型 | 解释 |
---|---|
text/html | HTML |
text/plain | 普通文本 |
application/json | Json |
6.3.1.4 状态码
状态码 | 解释 |
---|---|
200 | 请求成功 |
400 | 客户端请求语法错误 |
403 | 服务器拒绝请求 |
6.3.1.5 代码实例
6.3.2 JsonResponse:
6.3.2.1 概念
JsonResponse 是 HttpResponse 的子类.
6.3.2.2 子类和父类的区别
- JsonResponse 默认 Content-Type 类型为 application/json
- HttpResponse 默认为 application/text
- JsonResponse 只能序列化字典格式,不能序列化字符串,且前端不用反序列化
6.3.2.3 基础格式
代码部分:
from django.http import JsonResponse
def json_handler(request):
return JsonResponse( {"edu":"CSDN"}, course":"Python"}, )
注:JsonResponse接收字典只接受字典格式
当字典中出现中文,需要加入json_dumps_params={“ensure_ascii”:False}
例如:
def json_handler(request):
return JsonResponse( {"edu":"CSDN"}, course":"Python"},
json_dumps_params={"ensure_ascii":False})
6.3.2.4 代码实例
6.4 重定向
6.4.1 概念
当视图函数处理完成一个逻辑后,不需要向客户端呈现数据,而是转回到其它页面(可以理解为调用其它的视图函数) 通俗理解为:视图转向视图,即一个视图跳转到另一个视图.而不是直接返回到模板html.
6.4.2 基础格式
例如:
from django.shortcuts import redirect
def redirect_handler(request):
return redirect("/user") # 重定向到用户首页
# 通过reverse配合重定向
from django.shortcuts import reverse
def redirect_handler(request):
return redirect(reverse("user:index")) # 重定向到用户首页
注:这里使用到的 user:index 就是上边提到的命名空间和处理器命名的结合案例.
6.4.3 代码实例
7 Django-模板层
7.1 模板原理
7.1.1 模板语言
如图所示,HTML被直接硬编码在Python代码之中.尽管这种技术便于解释视图是如何工作的,但直接将HTML硬编码到你的视图里却并不符合我们的松耦合原则这样写有几处缺点:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zcxFDE0C-1575277751592)(image/1dd5827605a396936c12e727162f677f.png)]
- 对页面设计进行的任何改变都必须对Python代码进行相应的修改
- Python代码编写和HTML设计是两项不同的工作,大多数专业的网站开发环境都将他们分配给不同的程序人员来完成
- 程序员编写Python代码和设计人员制作网页模板两项工作同时进行的效率是最高的,远胜于让一个人等待另一个人完成.
- 基于这些原因,将页面的设计和Python的代码分离开会更干净简洁,容易维护.我们可以使用Django的模板系统(Template System)来实现这种模式
7.1.2 模板基础知识
模板是一个文本,用于分离文档的表现形式和内容.模板定义了占位符%,以及各种显示的基本逻辑,称作:模板标签.让我们从一个简单的例子模板开始
- 该模板是一段添加了些许变量和模板标签的基础HTML.让我们逐步分析一下:
- 第6行用两个大括号括起来的文字(例如{{ person_name}})称为变量(variable).这意味着在此处插入指定变量的值
- 第21行,被大括号和百分号包围的文本(例如{% if ordered_warranty%})是模板标签(templatetag).标签(tag)定义比较明确,即:仅通知模板系统完成某些工作的标签
- 第16行for标签类似Python的for语句,可让你循环访问序列里的每一个项,21行的if标签,用来执行逻辑判断
- Django模板含有很多内置的tags和filters,我们将陆续进行学习
7.1.3 模板系统
在terminal的终端输入命令python manage.py shell启动交互界面。直接创建一个Template并且直接实例化,注意在这里启动的是Django的shell交互界面,不是Python的交互界面.这里的运行机制是Python先运行manage.py,然后Django搜索DJANGO_SETTINGS_MODULE环境变量,它被设置在’books.settings’文件中,如图所示:
进行如下操作:
>>> from django.template import Template
>>> t = Template('My name is {{ name }}.')
>>> print(t)
你将会看到下面的内容
注:0x00000000041153C8每次都会不一样,这没什么关系;这只是Python运行时Template对象的ID.
7.1.4 模板渲染
当你创建一个Template对象,模板系统在内部编译这个模板到内部格式,并做优化,做好渲染的准备
一旦你创建一个Template对象,你可以用context来传递数据给它.一个context是一系列变量和它们值的集合。
7.2 模板组件
7.2.1 模板引擎配置
- 模板引擎使用该TEMPLATES设置进行配置。这是一个配置列表,每个引擎一个。
- 默认值为空。在 settings.py由所产生的startproject命令定义一个更有用的值:
- 在做下面模板配置的同时,也要在项目的根目录下创建一个templates目录
- 项目目录下的settings.py配置文件添加TEMPLATES中的DIRS配置:
7.2.2 模板语法—变量
- 语法: { { var } }
- 当模版引擎遇到一个变量,将计算这个变量,然后将结果输出
- 变量名必须由字母、数字、下划线(不能以下划线开头)和点组成
- 当模版引擎遇到点("."),会按照下列顺序查询:
- 字典查询,例如:foo[“bar”]
- 属性或方法查询,例如:foo.bar
- 数字索引查询,例如:foo[bar]
- 如果变量不存在, 模版系统将插入’’ (空字符串)
- 在模板中调用方法时不能传递参数
- {# … #}是模板语法中的注释
- 变量的调用方式
# 传递参数的构建:
context = { "key1":"value1", "key2":["value1","value2"], "key3":{ "key3_1":"value3_1", "key3_2":"value3_2", } }
#参数的调用方式: {# 1.普通值获取 #} {{ key1 }} {# 2.列表值获取 #} {{ key2.0}} {{ key2.1 }} {# 3.字典值获取 #} {{ key3.key3_1 }} {{ key3.key3_2 }}
7.2.3 模板语法—标签
- include:加载模板并以标签内的参数渲染,例如: { % include “base/index.html” % }
- url:反向解析 :
# 分两种情况:
# 主路由中存在namespace命名空间
#1 不需要额外传参的视图函数:
{% url "[namespace]:[name]" %}
#2 需要传参的视图函数:
{% url "[namespace]:[name]" [传递的参数]%}
#主路由中没有namespace命名空间
#1 不需要额外传参的视图函数:
{% url "[name]" %}
#2 需要传参的视图函数:
{% url "[name]" [传递的参数]%}
- csrf_token:这个标签用于跨站请求伪造保护, 例如:{ % csrf_token % }
7.2.4 模板语法—过滤器
7.2.4.1概念
模板过滤器是模板中对传递过来的数据进行修饰,再进行显示,在变量被显示前修改它的值的一个简单方法.过滤器使用的是管道字符,
7.2.4.2 语法
单个过滤器: {{ 变量|过滤器关键字:参数 }}
多个过滤器配合: {{ 变量|过滤器1|过滤器2 }}
例如: { { name|lower } },表示将变量name的值变为小写输出
注:
- 使用管道符号 (|)来应用过滤器
- 通过使用过滤器来改变变量的计算结果
- 关闭HTML自动转义
- 如果没有参数传递,可以不写
- 过滤管道可以被套接,一个过滤器管道的输出又可以作为下一个管道的输入,如此下去.下面的例子实现查找列表的第一个元素并将其转化为大写.例如:{{my_list|first|upper }}
关键字 | 说明 |
---|---|
safe | 禁止HTML转义 |
length | 长度 |
date | 日期(Y-m-d H:i:s) |
default | 默认值(变量|default:默认值) |
upper | 转大写 |
lower | 转小写 |
关键字 | 说明 |
safe | 禁止HTML转义 |
7.2.5 模板语法–继承与复用
7.2.5.1 模板继承
- 模板继承可以减少页面内容的重复定义,实现页面内容的重用
- 典型应用:网站的头部、尾部是一样的,这些内容可以定义在父模板中,子模板不需要重复定义
- extends继承:继承,写在模板文件的第一行
- 语法: {% extends “【父模板路径】” %}
实例:
{ % block block_name % }
这里可以定义默认值 如果不定义默认值,则表示空字符串
{ % endblock % }
7.2.5.2 模板复用
- block标签:在父模板中预留区域,在子模板中填充
- 语法:
{% block [代码块名称] %}
... ...
{% endblock %}
注:调用父模板中的代码:{{ block.supper }}
- 实例:定义子模板index.html
{ % extends "base.html" % }
在子模板中使用block填充预留区域
{ % block block_name % }
实际填充内容
{ % endblock % }
注:
- 不能在一个模版中定义多个相同名字的block标签
- 子模版不必定义全部父模版中的blocks,如果子模版没有定义block,则使用了父模版中的默认值
- 使用可以获取父模板中block的内容
- 为了更好的可读性,可以给endblock标签一个名字
7.2.6 模板语法—循环与判断
-
循环:
-
语法
{ % for ... in ... % } 循环逻辑 { % endfor % }
-
实例
#1.定义参数 context = { "hobbys":["Python","Java","C"] } #2.进行循环 {% for hobby in hobbys %} 爱好:{{ hobby }}<br/> {% endfor %}
注: {{ 用于输出变量 }} {% 命令语句 %}
-
-
判断
语法:
{ % if ... % }
逻辑1
{ % elif ... % }
逻辑2
{ % else % }
逻辑3
{ % endif % }