文章目录
Python云端开发
0.云端系统基础
全栈技术
技术 | 具体 |
---|---|
前端技术 | HTML CSS JavaScript |
云端接口 | JSON AJAX RESTful |
Web服务器 | Apache Nginx Tomcat |
Web框架 | Django Tornado Flask Pyramid |
业务逻辑 | Python |
数据库 | MySQL PostgresQL Mongo Sqlite |
HTML
Hyper Text Markup Language
超文本:声音、图像、视频
HTML是WWW(World Wide Web)的信息组织方式
对HTML的理解
- HTML本身是一段文本,由标签组成
- 浏览器负责解析HTML,并展示成Web页面内容
- HTML所使用的标签是预定义的,浏览器可解析
- HTML符合XML规范,是XML的一种实例
- HTML是组织不同类型数据的最好形式
HTML常用标签
功能 | 标签 |
---|---|
标题 | h1,h2,h3,h4,h5… |
段落 | p |
换行 | br |
容器 | div,span |
表格 | table,tr,td |
列表 | ul,ol,li |
链接 | a |
图片 | img |
表单 | input |
CSS
Cascading Style Sheets层叠样式表
HTML以标签形式,负责组织数据
CSS以键值对形式,负责样式表达
对CSS的理解
- HTML和不同的CSS的组合可以展示不同的风格
- CSS和不同的HTML组合,可以展示不同的风格
- CSS对HTML的某一“类”内容定义风格
- CSS可以单独存储成文件,或书写在HTML中
CSS的三种写法
- 行内模式:在标签的style属性中书写
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<ul>
<li style="color:red">Python网络爬虫</li>
<li style="color:red">Python云端系统开发</li>
<li>Python全栈能力</li>
</ul>
</body>
</html>
- 页内模式在HTML网页中使用独立的<style>标签书写
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Title</title>
<style type="text/css">
li {color:red}
</style>
</head>
<body>
<ul>
<li>Python网络爬虫</li>
<li>Python云端系统开发</li>
<li>Python全栈能力</li>
</ul>
</body>
</html>
- 外部模式:单独在CSS文件中书写
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="demo.css">
</head>
<body>
<ul>
<li>Python网络爬虫</li>
<li>Python云端系统开发</li>
<li>Python全栈能力</li>
</ul>
</body>
</html>
//下面是CSS代码
li {
color:red
}
JavaScript
JavaScript简称JS
JavaScript理解
- 一种轻量级的脚本型编程语言
- 为Web增加了交互、动态效果和行为功能
- JS由浏览器执行,访问时会被下载到本地
- JS可以写在HTML文件中,也可以单独为.js文件
JavaScript库理解
- 脚本型使得JS更容易开放开源
- 大量的JS库可以使用
- 希望什么效果,找个第三方库来使用
- echarts.js百度出品
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Title</title>
<script>
function displayDate() {
document.getElementById("time").innerHTML=Date();
}
</script>
</head>
<body>
<p id="time">这里将显示时间</p>
<ul>
<li>Python网络爬虫</li>
<li>Python云端系统开发</li>
<li>Python全栈能力</li>
</ul>
<button type="button" onclick="displayDate()">显示时间</button>
</body>
</html>
HTTP与Web服务器
HTTP协议
Hypertext Transfer Protocol超文本传输协议
HTTP是一个基于“请求与响应”模式的、无状态的应用层协议
HTTP协议采用URL作为定位网络资源的标识,URL格式如下
http://host[:port][path]
host:合法的Internet主机域名或IP地址
port:端口号,缺省端口为80
path:请求资源的路径
Web服务器
-
Web服务器是软件工具
-
Web服务器用于提供HTTP/HTTPS访问服务
-
Web服务器很成熟,只需要配置,不需要开发
-
常用的Web服务器软件:Apache、Nginx、IIS、BEA Weblogic、Tomcat、Node.js
1.云端系统框架基础
Django简介
- Django是一个Web框架
- Django是一个产品级框架,支撑全球近万个网站及云端
- 采用MTV(Model-Template-View)模型组织
- 相比其他框架,Django充分利用Python特点,开发效率更高
- 官方文档:https://docs.djangoproject.com/zh-hans/2.0/
Web框架
Web框架是一个建设Web应用的半成品
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2FrnkEMO-1630939839023)(Python云端开发.assets\image-20210709145901806.png)]
Django框架的最小程序
创建
步骤1
新建一个Web框架工程
cmd命令
\>django-admin startproject mysite
目录结构介绍
![image-20210709150038687](Python云端开发.assets\image-20210709150038687.png)
步骤2
2-1
创建一个具体的应用(app)
cmd命令
\>python manage.py startapp helloapp
工程和应用的关系
- 工程对应于一个网站,是配置和应用的集合
- 应用对应于特定功能,是具体功能的载体
- 配置和功能分离是高度模块化的体现
2-2
views.py中包含对某个HTTP请求(url)的响应
from django.shortcuts import render
# Create your views here.
from django.http import HttpResponse
def hello(request):
return HttpResponse("Hello World")
2-3
修改url路由
路由就是URL与处理函数的关联
在urls.py中指定URL与处理函数之间的路径关系
from django.contrib import adminfrom django.urls import include,pathfrom helloapp import viewsurlpatterns = [ path('index/',views.hello), path('admin/', admin.site.urls), #path 第一个参数指定用户访问的URL,第二个参数指定处理这个URL所使用的函数]
步骤3
调试运行Web框架
cmd命令
\>python manage.py runserver
http://127.0.0.1:8000/
Django自带调试用Web服务器
管理工具介绍
django-admin
cmd命令
\>django-admin <command> [options]\>django-admin help
django-admin是一个Django框架全局的管理工具
- 建立并管理Django工程
- 建立并管理Django工程使用的数据库
- 控制调试或日志信息
- 运行并维护Django工程
manage.py
cmd命令
\>python manage.py <command> [options]\>python manage.py help
与django-admin类似,但仅针对当前项目
Django框架的MTV开发模式
MTV解释
MTV | 说明 | 概括 |
---|---|---|
M:Models模型 | 与数据组织相关的功能,组织和存储数据的方法和模式,与数据模型相关的操作 | 数据组织 |
T:Templates模板 | 与表现相关的所有功能,页面展示风格和方式,与具体数据分离,用于定义表现风格 | Web展示 |
V:Views视图 | 针对请求选取数据的功能,选取哪些数据用于展示,指定显示模板,每个URL对应一个回调函数 | 控制逻辑 |
示意图
![image-20210630193218963](Python学习笔记.assets\image-20210630193218963.png)
![image-20210630193236447](Python学习笔记.assets\image-20210630193236447.png)
联系.py文件
- 模板T不默认生成,需要手工创建目录
- models.py针对某个app的模型M
- views.py针对某个app的视图V
- mysite/urls.py路由:Web框架的一部分
最小程序的改进
步骤2-1
新建hello2app应用
\>python manage.py startapp hello2app
步骤2-2
使用PYC01-HTMLJSDemo.html为返回页面,修改views.py
from django.shortcuts import render# Create your views here.from django.shortcuts import renderdef hello(request): return render(request,"PYC01-HTMLJSDemo.html")#render是一个打包函数,第一个参数是request,第一个参数是页面
步骤2-3
在hello2app应用中,新增urls.py文件(本地路由文件)
from django.urls import pathfrom . import views#.代表当前app#urlpatterns变量名是固定的urlpatterns=[ path('',views.hello)]
步骤2-4
在全局路由文件中增加对本应用路由文件的引用
from django.contrib import adminfrom django.urls import include,path#include函数用于引入其他路由文件from helloapp import viewsurlpatterns = [ path('index2/',include('hello2app.urls')),#将hello2app的局部路由增加到全局路由中 path('index/',views.hello), path('admin/', admin.site.urls),]
步骤2-5
设置模板路径,让Django框架找到模板所在目录
settings.py
TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR,'hello2app/templates')], # BASE_DIR当前工程主路径 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, },]
云端留言板
setting.py
'DIRS': [os.path.join(BASE_DIR,"msgapp/templates")],
urls.py
from django.contrib import adminfrom django.urls import include,pathurlpatterns = [ path('msggate/',include('msgapp.urls')), path('admin/', admin.site.urls),]
MsgSingleWeb.html
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>云端留言板(1)首页</title></head><body><h1>提交留言功能区</h1><form action="/msggate/" method="post"> {% csrf_token %} 发送方<input type="text" name="userA"/><br> 接收方<input type="text" name="userB"/><br> 消息文<input type="text" name="msg"/><br> <input type="submit" value="留言提交"/></form><h1>获取留言功能区</h1><form action="/msggate/" method="get"> 接收方<input type="text" name="userC"/><br> <input type="submit" value="留言获取"></form><table border="1"> <thead> <th>留言时间</th> <th>留言来源</th> <th>留言信息</th> </thead> <br> <tbody> {% for line in data %} <tr> <td>{{line.time}}</td> <td align="center">{{line.userA}}</td> <td>{{line.msg}}</td> </tr> {% endfor %} </tbody></table></body></html>
urls.py
from django.urls import pathfrom . import viewsurlpatterns=[ path('',views.msgproc),]
views.py
from django.shortcuts import renderfrom django.shortcuts import renderfrom datetime import datetime# Create your views here.def msgproc(request): datalist=[] if request.method=="POST": userA=request.POST.get("userA",None) userB=request.POST.get("userB",None) msg=request.POST.get("msg",None) time=datetime.now() with open('msgdata.txt','a+') as f: f.write("{}--{}--{}--{}--\n".format(userB,userA,msg,time.strftime("%Y-%m-%d %H:%M:%S"))) if request.method == "GET": userC = request.GET.get("userC", None) if userC != None: with open("msgdata.txt", "r") as f: cnt = 0 for line in f: linedata = line.split('--') if linedata[0] == userC: cnt = cnt + 1 d = {"userA":linedata[1], "msg":linedata[2], "time":linedata[3]} datalist.append(d) if cnt >= 10: break return render(request, "MsgSingleWeb.html", {"data":datalist})
2.云端系统框架进阶
Django的URL路由机制
Django的URL路由配置
路由是关联URL及其处理函数关系的过程
settings.py文件中的ROOT_URLCONF变量制定全局路由文件名称
ROOT_URLCONF = 'mysite.urls'
Django使用urlpatterns变量表示路由(urls.py),该变量是列表类型,由path()和re_path()作为元素组成
urlpatterns = [ path('',msgviews.homeproc2), path('msggate/',include('msgapp.urls')), path('admin/', admin.site.urls), path('playground/',msgviews.pgproc),]
Django的URL路由流程
- Django查找全局urlpatterns变量
- Django按照先后顺序,对URL逐一匹配urlpatterns的每个元素
- 在找到第一个匹配时停止查找,根据匹配结果执行对应处理函数
- 如果没有找到匹配或出现异常,Django进行错误处理
注意:
- Django的路由不考虑HTTP请求方式,仅根据URL进行路由
- 只要URL相同,无论POST、GET等哪种请求方式都指向同一个操作函数
路由:path()和re_path()
path()处理字符串路由
re_path()处理正则表达式路由
path(route,view)#route为URL字符串re_path(route,view)#route为一个正则表达式
路由函数
path(route,view,kwargs=None,name=None)
-
route:URL或URL模式,Django定义的URL转换语法
-
view:处理函数(视图函数)的名称,或include()类
-
kwargs:向处理函数提供的额外参数,以字典形式表示
-
name:给URL模式命名
route的格式和转换
Django支持三种方式表示route
精确字符串格式:articles/2003/
- 一个精确URL匹配一个操作函数
- 最简单形式,适合对静态URL的响应
- URL字符串不以/开头,但要以/结尾
articles/2003/
Django的转换格式:<类型:变量名>
- 一个URL模板,匹配URL同时在其中获得一批变量作为参数
- 常用形式,目的是通过URL进行参数获取和传递
- 采用<类型:变量名>格式获取参数
articles/2018/ -> articles/<int:year>/ -> 匹配year:2018articles/<int:year>/
转换格式类型
转换格式类型 | 说明 |
---|---|
str | 匹配除分隔符(/)外的非空字符串,默认类型:<year>等价于<str:year> |
int | 匹配0和正整数 |
slug | 匹配字母、数字、横杠、下划线组成的字符串,str的子集 |
uuid | 匹配格式化的uuid,例如a88155dd-2ee2-42eb-940b-6752f0d160cf |
path | 匹配任何非空字符串,包括路径分隔符,是全集 |
urlpatterns=[ path('articles/2003/',views.special_case_2003), path('articles/<int:year>',views.year_archive), path('articles/<int:year>/<int:month>/',views.month_archive) path('articles/<int:year>/<int:month>/<slug:msg>/',views.article_detail)]#请求URLarticles/2018/01/learn-django-mooc#匹配第四行#提取带类型的参数views.article_detail(request,year=2018,month=1,msg="learn-django-mooc")
正则表达式格式
- 借助正则表达式丰富语法表达一类URL
- 可以通过<>提取变量作为处理函数的参数,是个高级用法
- 使用re_path()函数
- 简单形式(pattern),不提取参数:articles/[0-9]{4}/
- 命名形式(?P<name>pattern),提取参数,统一为str类型:articles/(?P<year>[0-9]{4})/
articles/(?p<year>[0-9]{4}/
urlpatterns=[ re_path('articles/(?P<year>[0-9]{4}/)',views.year_archive), re_path('articles/(?P<year>[0-9]{4})/?P<month>[0-9]{2}/',views.month_archive), re_path('articles/(?P<year>[0-9]{4})/?P<month>[0-9]{2}/(?P<msg>[\w-_]+)/',views.articles_detail)]#请求URLarticles/2018/01/learn-django-mooc#匹配第三行#提取带类型的参数views.article_detail(request,year=“2018”,month=“01”,msg="learn-django-mooc")
view的使用
view包括两种类型:处理函数和include()函数
处理函数
views.py中处理URL的对应函数,URL处理的归宿
# appA/urls.pyurlpatterns=[ path('help/',views.help), path('sub/',views.sub),]
include()函数
include()函数包含其他路由信息的函数,分段路径组合形成总路径
# urls.pyurlpatterns=[ path('entry/',include('appA.urls'))]
# appA/urls.pyurlpatterns=[ path('help/',views.help), path('sub/',views.sub),]
http://127.0.0.1:8000/entry/help/ -> views.help()http://127.0.0.1:8000/entry/sub/ -> views.sub()
include()用法
- 附加本地路由
- 路径去重
urlpatterns=[ path('<page_slug>-<page_id>/history/',views.history), path('<page_slug>-<page_id>/edit/',views.edit), path('<page_slug>-<page_id>/discuss/',views.discuss), path('<page_slug>-<page_id>/permissions/',views.permissions),]
urlpatterns=[ path('<page_slug>-<page_id>/',include([ path('history/',views.history), path('edit/',views.edit), path('discuss/',views.discuss), path('permissions/',views.permissions), ]))]
URL根目录处理
http://127.0.0.1:8000/
#全局urls.py文件urlpatterns=[ path('',<根目录处理函数>), re_path('^$',<根目录处理函数>),#这俩二选一]
Django的视图响应类型
视图函数编写原则
视图函数接受HTTP请求并返回响应,可以放在任何地方,可以是任何功能
- 视图函数可以返回Web文本、页面、重定向、错误、图片等任何内容
- 视图函数通过HttpResponse、JsonResponse等类表达并返回响应
- 按约定,视图函数放在对应app的views.py文件中
Django的响应类型
HttpResponse类及其子类
类型 | 说明 |
---|---|
HttpResponse | 主要反馈类型,父亲,HTTP状态码默认200 |
HttpResponseRedirect | 重定向,HTTP状态码302 |
HttpResponsePermanentRedirect | 永久重定向,HTTP状态码301 |
HttpResponseNotModified | 网页无改动,该类型无任何参数,HTTP状态码304 |
HttpResponseBadRequest | 不良响应,HTTP状态码400 |
HttpResponseForbidden | 禁止访问,HTTP状态码403 |
HttpResponseNotAllowed | 不被允许,HTTP状态码405 |
HttpResponseGone | HTTP状态码410 |
HttpResponseServerError | 服务器错误,HTTP状态码500 |
HttpResponseNotFound | 404错误,HTTP状态码404 |
HttpResponse(content,content_type=None,status=200,charset=None)
- content:拟返回的字符串
- content_type:MIME格式的返回内容类型
- status:响应状态码
- charset:相应的字符集
例子
from django.contrib import adminfrom django.urls import include,pathfrom msgapp import views as msgviewsurlpatterns = [ path('',msgviews.homeproc2), path('msggate/',include('msgapp.urls')), path('admin/', admin.site.urls),]
def homeproc(request): return HttpResponse("<h1>这是首页,具体功能请访问<a href='./msggate'>这里</a></h1>")
def homeproc(request): response=HttpResponse() response.write("<h1>这是首页,具体功能请访问<a href='./msggate'>这里</a></h1>") response.write("<h1>这是第二行</h1>") return response
JsonResponse类
JsonResponse(data)
data:字典类型,返回的JSON类型数据
def homeproc1(request): response=JsonResponse({'key1':'value1'}) return response
StreamingHttpResponse类
StreamingHttpResponse(streaming_content)
streaming_content:内容的迭代器形式,以内容流的方式响应
流式响应
FileResponse类
FileResponse(stream)
stream:以流形式打开后的文件
def homeproc2(request): cwd=os.path.dirname(os.path.dirname(os.path.abspath(__file__))) response=FileResponse(open(cwd+"/msgapp/templates/PyLogo.png","rb")) response['Content-Type']='application/octet-stream' response['Content-Disposition']='attachment;filename="pylogo.png"'#默认文件名 return response
Django请求类型的判断
django.views.decorators.http
- 路由不能判断HTTP请求的类型
- Django通过decorators在视图函数前进行基本判断,格式如下
from django.views.decorators.http import require_http_methods@require_http_methods(["GET","POST"])def my_view(request): #I can assume now that only GET or POST requests make it this far #... pass
Django的视图流式响应机制
Django响应类型
一次响应:HttpResponse类及其子类、JsonResponse类
流式响应:StreamingHttpResponse类、FileResponse类,适合大文本文件大二进制文件传输
实例:文件下载
HttpResponse方式
def file_download(request): #do sth with open('data.txt')as f: c=f.read() return HttpResponse(c)#文件一次性响应,仅适合小文件
StreamingHttpResponse方式
- 将文件分段,每次传输一部分,分段大小可调
- 利用Python的迭代器产生分段
- 可以是文件,也可以是任何大规模数据响应
from django.http import StreamingHttpResponsedef big_file_download(request): #do sth def file_iterator(file_name,chunk_size=512): with open(file_name)as f: while True: c=f.read(chunk_size) if c: yield c else: breakfname="data.txt"response=StreamingHttpResponse(file_iterator(fname))return response
yield关键字
-
yield等价于生成器
-
包含yield语句的函数是一个生成器(迭代器的一种)
-
生成器每次产生一个值(yield语句),之后函数被冻结,被唤醒后再产生一个值
-
生成器就是一个不断产生值的函数
FileResponse方式
- FileResponse是StreamingHttpResponse的子类
- 自动分段、自动迭代、适合二进制文件传输
def homeproc2(request): cwd=os.path.dirname(os.path.dirname(os.path.abspath(__file__))) response=FileResponse(open(cwd+"/msgapp/templates/PyLogo.png","rb")) response['Content-Type']='application/octet-stream' response['Content-Disposition']='attachment;filename="pylogo.png"' return response
MIME标记
response['Content-Type']='application/octet-stream' response['Content-Disposition']='attachment;filename="pylogo.png"'
- Content-Type用于指定文件类型
- Content-Disposition用于指定下载文件的默认名称
- 这两者是MIME类型的标准定义
Django的模板引擎与模板使用
Django模板引擎
![image-20210701191203933](Python学习笔记.assets\image-20210701191203933.png)
模板引擎的配置
settings.py中的BACKEND
TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates',#引擎配置 'DIRS': [os.path.join(BASE_DIR,"msgapp/templates")],#模板目录,模板目录在列表中的顺序是搜索模板的顺序 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, },]
模板的查找
get_template(template_name) -> Template类
在模板目录列表中依次查找某个模板,直到找到并返回Template类
如果未找到模板,则抛出TemplateDoesNotExist异常
template_name:待查找模板的名称
select_template(template_name_list) -> Template类
依次按照模板列表查找某个模板,直到找到第一个,并返回Template类
如果未找到模板,则抛出TemplateDoesNotExist异常
template_name_list:待查找模板名称列表
模板的渲染
Template.render(context,request) -> HTML字符串
模板对象的.render()方法用于将模板结合内容渲染从HTML字符串
将模板和内容整合到一起,返回HTML字符串
context:字典类型,用于加载到模板中的内容
request:HTTP请求
try: tpl=get_template("MsgSingleWeb.html")except: return HttpResponseNotFound("<h1>自定义的404</h1>")html=tpl.render({"data":datalist},request)return HttpResponse(html)
![image-20210709195441157](Python云端开发.assets\image-20210709195441157.png)
def pgproc(request): template=Template("<h1>这个程序的名字是{{name}}</h1>") context=Context({"name" : "实验平台"}) return HttpResponse(template.render(context))
Django的模板语言入门
模板语言:指导模板加载数据方式的工具
DTL:Django Template Language
注释comment
单行注释
{# 这是单行注释 #}
多行注释
{% comment %} 这是多行注释第一行 这是多行注释第二行{% endcomment %}
变量variable
{{name}}{{adict.key}}{{alist.0}}{{aovject.attribute}}
标签tags
{ %关键字引导的程序逻辑% }
标签中的关键字包括:
for、endfor,block、endblock,if、elif、else、endif,in,trans,as,with,extends等
{% for line in data %}<tr> <td>{{line.time}}</td> <td align="center">{{line.userA}}</td> <td>{{line.msg}}</td></tr>{% endfor %}
过滤器filter
{{name|过滤标签}}{{name|f1|f1}}
过滤器对变量的值进行修饰
lower,escape,linebreaks,date,length等
{{name|lower}}{{my_date|date:"Y-m-d"}}