一、引子
1.什么是web应用?
Web应用程序是一种可以通过Web访问的应用程序,程序的最大好处是用户很容易访问应用程序,用户只需要有浏览器即可,不需要再安装其他软件。
2.软件开发架构
C/S 架构
- 客户端
- 服务端
B/S架构:本质也是C/S架构
- 浏览器
- 服务器
3.HTTP协议
超文本传输协议,规定了客户端与服务端消息传输的格式。
四大特性:
- 基于TCP/IP协议作用于应用层的协议
- 基于请求响应
- 无状态(你我连接千万次,我仍待你如初识)
- 无连接
数据格式之请求:
- 请求首行
- 请求头(一堆k,v键值对)
- (空格)
- 请求体(post请求携带的数据)
数据格式之响应:
- 响应首行
- 响应头(一堆k,v键值对)
- (空格)
- 响应体(你想访问的数据)
响应状态码
- 1XX 服务器已经成功接受到你的数据正在处理,你可以继续提交其他数据
- 2XX 请求成功 服务器已经将你请求的数据发送给你了
- 3XX 重定向
- 4XX 请求资源不存在
- 5XX 服务器错误
二、简易版本web请求响应
1.找到用户访问的页面路径
<!--数据格式之请求-->
<!--请求首行-->
GET /index HTTP/1.1/r/n
<!--请求头-->
Host: 127.0.0.1:8080/r/n
Connection: keep-alive/r/n
Pragma: no-cache/r/n
Cache-Control: no-cache/r/n
Upgrade-Insecure-Requests: 1/r/n
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36/r/n
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3/r/n
Accept-Encoding: gzip, deflate, br/r/n
Accept-Language: zh-CN,zh;q=0.9/r/n
<!--空格-->
/r/n
<!--请求体-->
'
- 将请求bytes转成字符串(decode)
- 用split方法按/r/n切,取列表的第一个元素,即取到请求首行GET /index HTTP/1.1
- 再按空格切,取第二元素,即得到/index,就是用户访问的页面路径。
2.基于wsgiref模块
我们得到用户访问的路径,即可根据用户的需求返回相应的内容(HTML文件)到用户浏览器。当然我们不必自己造轮子,我们可以基于wsgiref模块完成上述过程。
from wsgiref.simple_server import make_server
from urls import *
def run(env,response):
"""
:param env: 请求相关的信息
:param response: 响应相关的信息
:return:
"""
print(env) # 是一个大字典 里面装了一堆处理好了的键值对数据
response('200 OK',[('username','jason'),('password','123')]) # 固定写法 后面列表里面一个个元祖会以响应头kv键值对的形式返回给客户端
# 获取用户访问的路径
current_path = env.get('PATH_INFO')
if current_path == '/index':
return [b'index']
elif current_path == '/login':
return [b'login']
return [b'hello]
if __name__ == '__main__':
server = make_server('127.0.0.1',8080,run)
server.serve_forever()
3.进阶版本
我们在判断用户访问路径的时候,过多的if判断会显得整个代码冗长累赘,可读性差,所以我们要拆分代码。定义一个字典来对应函数功能。
from wsgiref.simple_server import make_server
from urls import *
def index(env):
return 'index'
def login(env):
return 'login'
def error(env):
return '404 error'
urls = {
('/index',index),
('/login',login),
}
def run(env,response):
"""
:param env: 请求相关的信息
:param response: 响应相关的信息
:return:
"""
print(env) # 是一个大字典 里面装了一堆处理好了的键值对数据
response('200 OK',[('username','jason'),('password','123')]) # 固定写法 后面列表里面一个个元祖会以响应头kv键值对的形式返回给客户端
# 获取用户访问的路径
current_path = env.get('PATH_INFO')
func = None
# 循环比对路由与试图函数的映射关系
for url_map in urls: # url_map = ('/index',index)
if current_path == url_map[0]:
func = url_map[1]
# 只要匹配成功 直接结束循环
break
if func:
res = func(env)
else:
res = error(env)
return [res.encode('utf-8')] # 最后再统一编码
if __name__ == '__main__':
server = make_server('127.0.0.1',8080,run)
server.serve_forever()
最终我们可以将视图函数归于一个文件views.py,映射关系归于另一个文件urls.py。这样当我们需要增加用户路径的时候只需要在urls.py中添一条对应关系,在views.py中定义函数功能即可,实现了解耦合操作。我们的HTML文件可以放在一个名为templates文件夹中。
三、模板渲染
后端生成的数据直接传递给前端页面使用(并且前端页面可以灵活的操作改数据)
动静态网页
静态网页:页面上的数据都是写死的,万年不变
动态网页:页面上的数据是从后端动态获取的。比如后端获取当前时间,后端获取数据库数据然后传递给前端页面。
栗子:从后端获取时间在前端显示。
# 在views.py文件中
def get_time(env):
# 先获取当前时间
current_time = time.strftime('%Y-%m-%d %X')
# 打开html文件读取内容返回给客户端
with open(r'templates/get_time.html','r',encoding='utf-8') as f:
data = f.read()
# 因为是以r模式打开的文件,所有获取到的内容就是一堆字符串,在get_time.html文件中用@@time@@占位
res = data.replace('@@time@@',current_time) # 字符串的替换
return res
模板语法
依赖于第三方模块,例如jinja2,jinja2支持前端直接使用类似于python的语法操作数据
<p>{{ user_dic }}</p>
<p>{{ user_dic.name }}</p>
<p>{{ user_dic['name'] }}</p>
<p>{{ user_dic.get('name') }}</p>
<!--for循环语句-->
{% for user in user_dict %} <!--[{},{},{},{}]-->
{% endfor %}
四、web框架?
python三大主流web框架
- Django:大而全,自带了很多功能模块,类似于航空母舰 (缺点:有点笨重)
- Flask:短小精悍,自带的功能模块特别少,大部分都是依赖于第三方模块(小而轻)
- Tornado:异步非阻塞 主要用在处理高io 多路复用的情况 可以写游戏后端
框架组成部分
- a:socket
- b:路由与视图函数
- c:模板渲染
Django:
a用的别人的 wsgiref
b自己写的
c自己写的
Flask:
a用的别人的 werkzeug
b自己写的
c用的别人的 jinja2
Tornado:
a,b,c都是自己写的
五、Django安装及注意事项
下载方式
1.命令行直接下载
pip3 install django==1.11.11
2.pycharm下载
创建django项目的方式
方式1(命令行创建):
创建django项目
django-admin startproject 项目名
创建app应用
python3 manage.py startapp app01
(首先要切换到项目文件夹,另外注意python3.7只兼容django2.0及以上版本)
启动django项目
python3 manage.py runserver
ps:用命令行创建django默认不会自动创建templates文件夹
需要你手动自己创建(注意改文件夹路径是否被添加配置文件中)
方式2(pycharm创建)
创建django项目
FILE >>> new project 选择第二个django 需要注意名字不能有中文,选择本地的解释器,勾选后台管理
创建app
pycharm命令行创建
python3 manage.py startapp app01
Tools下面run manage task功能栏
启动点小绿色箭头
强调:
1.用django一定要保证只有一个在运行状态 切记切记!!!!!!!
2.一定记得清浏览器的缓存
app(应用)的概念
一个django项目就是一所大学,app就是大学里面的学院
注意新创建的app需要在配置文件中注册才能生效(*******************)
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app01.apps.App01Config' # 可以用全称
'app01' # 也可以简写
]
django各个文件的作用
应用名
migrations 数据库迁移记录相关数据
admin.py django后台管理相关
models.py 模型表相关
views.py 视图函数相关
项目名
settings.py 配置文件
urls.py 路由与视图函数的映射关系
templates
项目用到的所有的html文件
manage.py
django入口文件
六、django小白必会三板斧
from django.shortcuts import render,HttpResponse,redirect
HttpResponse 返回字符串
render 返回一个html页面
两种给前端页面传值的方式
def reg(request):
user_dict = {'name':'jason','password':'123'}
return render(request,'reg.html',{'user_dict':user_dict})
def reg(request):
user_dict = {'name':'jason','password':'123'}
return render(request,'reg.html',locals())