准备工作

   在学习Django之前,先动手撸一个简单的WEB框架来熟悉一下前后端交互的整体流程

   本次用到的模块:

   1.wsgiref,这是一个Python自带的模块,用于构建路由与视图

   2.pymysql,第三方模块,用于数据库与视图层进行数据交互

   3.jinja2,第三方模块,用于对前端页面进行模板渲染

   请使用pip install modulename进行安装

   如果安装jinja2失败,请使用easy_install Jinja2命令进行安装

数据交互

   其实前面已经有大量的地方讨论浏览器与后端服务器如何进行交互,也用socket进行实现过简单的交互,但是我们需要在前者基础上做一个优化,即用户在地址栏输入什么路径,就返回请求的路径名字。

   当这个需求完成后,我们就可以根据不同的请求路径,返回出不同的HTML文档信息,但是使用原生的socket这个过程会十分的繁琐,所以用一次就放弃吧。

from socket import *

def run():
server = socket(AF_INET, SOCK_STREAM) # 传输层基于TCP协议
server.bind(("127.0.0.1", 8080))
server.listen(5) while 1: conn, addr = server.accept()
try: # 防止Windows平台下Client端异常关闭导致双向链接崩塌Server端异常的情况发生
data = conn.recv(1024)
if not data: # bug修复:针对类UNIX环境
continue request_path = data.decode("utf-8").split(" ")[1] # 拿到请求的路径
conn.sendall(bytes("HTTP/1.1 201 OK \r\n\r\n", "utf8")) # 返回响应头
conn.sendall(bytes("<h1>{0}</h1>".format(request_path), "utf8")) # 返回响应体 except Exception:
continue conn.close() if __name__ == '__main__':
run()

  

wsgiref

   以下是利用wsgiref实现上面的功能,简单了许多,并且代码变得更加明了。

   此外新增加了访问路径不存在时给出404错误提示。

from wsgiref.simple_server import make_server

def index(request):
return "You visited index" def login(request):
return "You visited login" def error(request):
return "404 Resource request error" urls = [
("/index", index),
("/login", login),
] def run(request, response): """
request:① 请求相关的所有数据
response:② 响应相关的数据
return:③ 返回给浏览器的数据
""" response("200 OK",[]) # 响应首行,响应头
func = None
request_path = request.get("PATH_INFO") # 拿到路径 for url in urls:
if request_path == url[0]:
func = url[1]
break # 匹配到后结束for循环 if func:
res = func(request)
else:
res = error(request) return [res.encode("utf-8")] if __name__ == '__main__':
server = make_server("localhost", 8080, run)
# ③ 实时监听127.0.0.1:8080地址,只要有链接请求,都交给run函数处理
server.serve_forever() # ④ 开启服务

  

代码解耦

   我们对上述代码进行解耦,将不同功能的代码放在不同的文件夹下。

  

-- webproject
-- view # 视图相关代码
-- view.py
-- urls # 路由相关代码
-- urls.py
-- run.py # 启动相关代码
# view.py

def index(request):
return "You visited index" def login(request):
return "You visited login" def error(request):
return "404 Resource request error"
# urls.py

from view.view import *

urls = [
("/index", index),
("/login", login),
]
# run.py

from wsgiref.simple_server import make_server
from urls.urls import * def run(request, response): """
request:① 请求相关的所有数据
response:② 响应相关的数据
return:③ 返回给浏览器的数据
""" response("200 OK",[]) # 响应首行,响应头
func = None
request_path = request.get("PATH_INFO") # 拿到路径 for url in urls:
if request_path == url[0]:
func = url[1]
break # 匹配到后结束for循环 if func:
res = func(request)
else:
res = error(request) return [res.encode("utf-8")] if __name__ == '__main__':
server = make_server("localhost", 8080, run)
# ③ 实时监听127.0.0.1:8080地址,只要有链接请求,都交给run函数处理
server.serve_forever() # ④ 开启服务

返回页面

   继续上面的流程,已经将代码进行解耦了,此时我们新建一个template文件夹用于专门存放返回的网页。

   并在该文件夹下新建index.html以及login.html

-- webproject
-- view # 视图相关代码
-- view.py
-- urls # 路由相关代码
-- urls.py
-- template # 前端页面
-- index.html
-- login.html
-- run.py # 启动相关代码

<!DOCTYPE html>
<html lang="en"> <head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src='https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.js'></script>
<link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css'
integrity='sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u' crossorigin='anonymous'>
<script src='https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js'
integrity='sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa'
crossorigin='anonymous'></script>
<title>Document</title>
<style> .carousel .item {
height: 400px;
background-color: #777;
} .carousel-inner>.item>img {
position: absolute;
top: 0;
left: 0;
min-width: 100%;
height: 100%;
}
</style>
</head> <body> <nav class="navbar navbar-inverse">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">INDEX</a>
</div> <!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<form class="navbar-form navbar-left">
<div class="form-group">
<input type="text" class="form-control" placeholder="Search">
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
<ul class="nav navbar-nav navbar-right">
<li><a href="HTTP://127.0.0.1:8080/login">LOGIN</a></li>
<li><a href="#">REGISTER</a></li>
</ul>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav> <div class="container-fluid"> <div class="row">
<div class="col-xs-12 col-sm-12 col-md-12 col-lg-12 input-lg-5g bg-primar ">
<div class="page-header">
<h1>Example page header <small>Subtext for header</small></h1>
</div>
</div> <div class="col-xs-3 col-sm-3 col-md-3 col-lg-3">
<div class="list-group">
<a href="#" class="list-group-item active">
Cras justo odio
</a>
<a href="#" class="list-group-item">Dapibus ac facilisis in</a>
<a href="#" class="list-group-item">Morbi leo risus</a>
<a href="#" class="list-group-item">Porta ac consectetur ac</a>
<a href="#" class="list-group-item">Vestibulum at eros</a>
</div>
</div> <div class="col-xs-9 col-sm-9 col-md-9 col-lg-9">
<div id="carousel-example-generic" class="carousel slide" data-ride="carousel">
<!-- Indicators -->
<ol class="carousel-indicators">
<li data-target="#carousel-example-generic" data-slide-to="0" class="active"></li>
<li data-target="#carousel-example-generic" data-slide-to="1"></li>
</ol> <!-- Wrapper for slides -->
<div class="carousel-inner">
<div class="item active">
<img src="https://tse4-mm.cn.bing.net/th/id/OIP._PbxAuEi3ce9S1DtQ3KilwHaEK?w=306&h=180&c=7&o=5&dpr=1.25&pid=1.7"
alt="...">
</div>
<div class="item">
<img src="https://tse2-mm.cn.bing.net/th/id/OIP.Det5e8us-qsNAGEhnL6u0AHaF7?w=238&h=190&c=7&o=5&dpr=1.25&pid=1.7"
alt="...">
</div>
</div> <!-- Controls -->
<a class="left carousel-control" href="#carousel-example-generic" role="button" data-slide="prev">
<span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
<a class="right carousel-control" href="#carousel-example-generic" role="button" data-slide="next">
<span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
</div>
</div> </div> </div> </body> </html>

index.html

<!DOCTYPE html>
<html lang="en"> <head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src='https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.js'></script>
<link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css'
integrity='sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u' crossorigin='anonymous'>
<script src='https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js'
integrity='sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa'
crossorigin='anonymous'></script> <style>
body {
display: flex;
justify-content: center;
align-self: center;
height: 100vh;
background-color: rebeccapurple; } form.form1 {
display: flex;
flex-flow: column;
justify-content: center;
align-self: center;
border: 1px solid #ddd;
padding: 10px;
width: 30%;
background-color: white;
border-radius: 15px;
}
</style> </head> <body> <form class="form1" action="#">
<div class="form-group">
<label for="exampleInputEmail1">username</label>
<input type="email" class="form-control" id="exampleInputEmail1" placeholder="please enter user name">
</div>
<div class="form-group">
<label for="exampleInputPassword1">Password</label>
<input type="password" class="form-control" id="exampleInputPassword1"
placeholder="please enter user password">
</div> <button type="submit" class="btn btn-default" disabled>Submit</button>
</form> </body> </html>

login.html

   除此之外,还要将视图中index函数与login函数的返回结果改一下

# view.py

def index(request):
with open(file="template/index.html",mode="r",encoding="utf-8") as f:
res = f.read()
return res def login(request):
with open(file="template/login.html",mode="r",encoding="utf-8") as f:
res = f.read()
return res def error(request):
return "404 Resource request error"

view.py

   那么目前,我们的框架已经初具雏形了,能够根据请求路径的不同返回不同的HTML文档。

pymsql

   继续接着做逻辑,点击login后输入用户名和密码提交完应该对数据库进行验证,判断该用户是否存在。

   那么现在我们就需要用到pymysql模块了,还是新建一个文件夹叫db,然后创建db文件进行操作。

import pymysql

class DbServer(object):
def __init__(self):
self.conn = pymysql.connect(
host="localhost",
database="db1",
charset="utf8mb4",
user="root",
cursorclass=pymysql.cursors.DictCursor, # 记录结果,字典显示
autocommit=True, # 自动提交
) self.cursor = self.conn.cursor() def select(self, sql, val=None):
res = self.cursor.execute(sql, val)
return res, self.cursor.fetchone() # 返回查找行数,查找结果 def insert(self, sql, val=None):
pass def drop(self, sql, val=None):
pass def deletle(self, sql, val=None):
pass def __del__(self):
# 关闭程序前关闭链接与游标
self.cursor.close()
self.conn.close() if __name__ != '__main__': # 不能当作独立文件进行运行
dbserver = DbServer()

db.py

   记得在数据库中先插入数据

create table user(
id INT PRIMARY KEY AUTO_INCREMENT,
name CHAR(12) NOT NULL,
password CHAR(12) NOT NULL,
INDEX(name) -- 添加索引
); INSERT INTO user(name,password) VALUES
("Yunya","");

MySQL命令

   别忘了在view.py中进行导入,与此同时,还要写一个验证功能。

from db.db import dbserver
import jinja2 def index(request):
with open(file="template/index.html", mode="r", encoding="utf-8") as f:
res = f.read()
return res def login(request):
with open(file="template/login.html", mode="r", encoding="utf-8") as f:
res = f.read()
return res def login_verif(request):
# GET 请求 QUERY_STRING
request_msg = request.get("QUERY_STRING", None).split("&")
user_dict = {} for msg in request_msg:
key, value = msg.split("=")
user_dict[key] = value
from db.db import dbserver def index(request):
with open(file="template/index.html", mode="r", encoding="utf-8") as f:
res = f.read()
return res def login(request):
with open(file="template/login.html", mode="r", encoding="utf-8") as f:
res = f.read()
return res def login_verif(request):
# GET 请求 QUERY_STRING
request_msg = request.get("QUERY_STRING", None).split("&")
user_dict = {} for msg in request_msg:
key, value = msg.split("=")
user_dict[key] = value sql = "select * from user where name=%s and password = %s"
val = (user_dict.get("username"), user_dict.get("password"))
result = dbserver.select(sql, val)
if result[0]:
return "Welcome" + result[1].get("name")
else:
return "Login failed, no such user" def error(request):
return "404 Resource request error"

view.py

   还要在urls.py文件中增加验证的路由解析。

from view.view import *

urls = [
("/index", index),
("/login", login),
("/login_verif", login_verif),
]

urls.py

   最后一步修改前端login.html中的form提交路径

  <form class="form1" action="http://127.0.0.1:8080/login_verif">
<div class="form-group">
<label for="username">username</label>
<input type="text" id="username" name="username" class="form-control" placeholder="please enter user name">
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" id="password" name="password" class="form-control"
placeholder="please enter user password">
</div> <button type="submit" class="btn btn-default">Submit</button>
</form>

login.html

jinja2

   在验证完成后,我们应该根据用户名与密码是否正确来返回不同的内容。

   这个时候可以使用jinja2的模板语言了。

   首先在Template文件夹下新建一个verification.html做验证

   然后修改一下view中的login_verif代码

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body> <div class="container"> <div class="row">
<div class="col-xs-6 col-sm-6 col-md-6 col-lg-6 col-xs-offset-3 col-sm-offset-3 col-md-offset-3 col-lg-offset-3 ">
<div class="page-header">
{% if login_msg.status %}
<h1>欢迎回家{{login_msg.username}}</h1>
{% else %}
<h1>无此用户!请检查用户名或密码是否输入正确</h1>
{% endif %}
</div>
</div>
</div> </div> </body>
</html>

verification.html

def login_verif(request):
# GET 请求 QUERY_STRING
request_msg = request.get("QUERY_STRING", None).split("&")
user_dict = {} for msg in request_msg:
key, value = msg.split("=")
user_dict[key] = value sql = "select * from user where name=%s and password = %s"
val = (user_dict.get("username"), user_dict.get("password"))
result = dbserver.select(sql, val) with open("./template/verification.html","r",encoding="utf-8") as f:
data = f.read() tmp = jinja2.Template(data) # 做成模板 if result[0]:
msg = {"username":result[1].get("name"),"status":1} else:
msg = {"username":None,"status":0} res = tmp.render(login_msg=msg) # 模板中添加变量
return res

view.py def login_verif

成果演示

代码总和

   db - db.py

import pymysql

class DbServer(object):
def __init__(self):
self.conn = pymysql.connect(
host="localhost",
database="db1",
charset="utf8mb4",
user="root",
cursorclass=pymysql.cursors.DictCursor, # 记录结果,字典显示
autocommit=True, # 自动提交
) self.cursor = self.conn.cursor() def select(self, sql, val=None):
res = self.cursor.execute(sql, val)
return res, self.cursor.fetchone() # 返回查找行数,查找结果 def insert(self, sql, val=None):
pass def drop(self, sql, val=None):
pass def deletle(self, sql, val=None):
pass def __del__(self):
# 关闭程序前关闭链接与游标
self.cursor.close()
self.conn.close() if __name__ != '__main__':
dbserver = DbServer()

   template - index.html

<!DOCTYPE html>
<html lang="en"> <head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src='https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.js'></script>
<link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css'
integrity='sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u' crossorigin='anonymous'>
<script src='https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js'
integrity='sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa'
crossorigin='anonymous'></script>
<title>Document</title>
<style> .carousel .item {
height: 400px;
background-color: #777;
} .carousel-inner>.item>img {
position: absolute;
top: 0;
left: 0;
min-width: 100%;
height: 100%;
}
</style>
</head> <body> <nav class="navbar navbar-inverse">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">INDEX</a>
</div> <!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<form class="navbar-form navbar-left">
<div class="form-group">
<input type="text" class="form-control" placeholder="Search">
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
<ul class="nav navbar-nav navbar-right">
<li><a href="HTTP://127.0.0.1:8080/login">LOGIN</a></li>
<li><a href="#">REGISTER</a></li>
</ul>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav> <div class="container-fluid"> <div class="row">
<div class="col-xs-12 col-sm-12 col-md-12 col-lg-12 input-lg-5g bg-primar ">
<div class="page-header">
<h1>Example page header <small>Subtext for header</small></h1>
</div>
</div> <div class="col-xs-3 col-sm-3 col-md-3 col-lg-3">
<div class="list-group">
<a href="#" class="list-group-item active">
Cras justo odio
</a>
<a href="#" class="list-group-item">Dapibus ac facilisis in</a>
<a href="#" class="list-group-item">Morbi leo risus</a>
<a href="#" class="list-group-item">Porta ac consectetur ac</a>
<a href="#" class="list-group-item">Vestibulum at eros</a>
</div>
</div> <div class="col-xs-9 col-sm-9 col-md-9 col-lg-9">
<div id="carousel-example-generic" class="carousel slide" data-ride="carousel">
<!-- Indicators -->
<ol class="carousel-indicators">
<li data-target="#carousel-example-generic" data-slide-to="0" class="active"></li>
<li data-target="#carousel-example-generic" data-slide-to="1"></li>
</ol> <!-- Wrapper for slides -->
<div class="carousel-inner">
<div class="item active">
<img src="https://tse4-mm.cn.bing.net/th/id/OIP._PbxAuEi3ce9S1DtQ3KilwHaEK?w=306&h=180&c=7&o=5&dpr=1.25&pid=1.7"
alt="...">
</div>
<div class="item">
<img src="https://tse2-mm.cn.bing.net/th/id/OIP.Det5e8us-qsNAGEhnL6u0AHaF7?w=238&h=190&c=7&o=5&dpr=1.25&pid=1.7"
alt="...">
</div>
</div> <!-- Controls -->
<a class="left carousel-control" href="#carousel-example-generic" role="button" data-slide="prev">
<span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
<a class="right carousel-control" href="#carousel-example-generic" role="button" data-slide="next">
<span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
</div>
</div> </div> </div> </body> </html>

   template - login.html

<!DOCTYPE html>
<html lang="en"> <head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src='https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.js'></script>
<link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css'
integrity='sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u' crossorigin='anonymous'>
<script src='https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js'
integrity='sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa'
crossorigin='anonymous'></script> <style>
body {
display: flex;
justify-content: center;
align-self: center;
height: 100vh;
background-color: rebeccapurple; } form.form1 {
display: flex;
flex-flow: column;
justify-content: center;
align-self: center;
border: 1px solid #ddd;
padding: 10px;
width: 30%;
background-color: white;
border-radius: 15px;
}
</style> </head> <body> <form class="form1" action="http://127.0.0.1:8080/login_verif">
<div class="form-group">
<label for="username">username</label>
<input type="text" id="username" name="username" class="form-control" placeholder="please enter user name">
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" id="password" name="password" class="form-control"
placeholder="please enter user password">
</div> <button type="submit" class="btn btn-default">Submit</button>
</form> </body> </html>

   template - verifcation.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body> <div class="container"> <div class="row">
<div class="col-xs-6 col-sm-6 col-md-6 col-lg-6 col-xs-offset-3 col-sm-offset-3 col-md-offset-3 col-lg-offset-3 ">
<div class="page-header">
{% if login_msg.status %}
<h1>欢迎回家{{login_msg.username}}</h1>
{% else %}
<h1>无此用户!请检查用户名或密码是否输入正确</h1>
{% endif %}
</div>
</div>
</div> </div> </body>
</html>

   urls - urls.py

from view.view import *

urls = [
("/index", index),
("/login", login),
("/login_verif", login_verif),
]

   view - view.py

from db.db import dbserver
import jinja2 def index(request):
with open(file="template/index.html", mode="r", encoding="utf-8") as f:
res = f.read()
return res def login(request):
with open(file="template/login.html", mode="r", encoding="utf-8") as f:
res = f.read()
return res def login_verif(request):
# GET 请求 QUERY_STRING
request_msg = request.get("QUERY_STRING", None).split("&")
user_dict = {} for msg in request_msg:
key, value = msg.split("=")
user_dict[key] = value
from db.db import dbserver def index(request):
with open(file="template/index.html", mode="r", encoding="utf-8") as f:
res = f.read()
return res def login(request):
with open(file="template/login.html", mode="r", encoding="utf-8") as f:
res = f.read()
return res def login_verif(request):
# GET 请求 QUERY_STRING
request_msg = request.get("QUERY_STRING", None).split("&")
user_dict = {} for msg in request_msg:
key, value = msg.split("=")
user_dict[key] = value sql = "select * from user where name=%s and password = %s"
val = (user_dict.get("username"), user_dict.get("password"))
result = dbserver.select(sql, val) with open("./template/verification.html","r",encoding="utf-8") as f:
data = f.read() tmp = jinja2.Template(data) if result[0]:
msg = {"username":result[1].get("name"),"status":1} else:
msg = {"username":None,"status":0} res = tmp.render(login_msg=msg) # 返回登录信息
return res def error(request):
return "404 Resource request error"

   run.py

from wsgiref.simple_server import make_server
from urls.urls import * def run(request, response): """
request:① 请求相关的所有数据
response:② 响应相关的数据
return:③ 返回给浏览器的数据
""" response("200 OK",[]) # 响应首行,响应头
func = None
request_path = request.get("PATH_INFO") # 拿到路径 for url in urls:
if request_path == url[0]:
func = url[1]
break # 匹配到后结束for循环 if func:
res = func(request)
else:
res = error(request) return [res.encode("utf-8")] if __name__ == '__main__':
server = make_server("localhost", 8080, run)
# ③ 实时监听127.0.0.1:8080地址,只要有链接请求,都交给run函数处理
server.serve_forever() # ④ 开启服务

最后结论

   其实通过这三个基础模块,相信你已经了解了其基本的流程,但是用这三个模块来做成一个建议的Web框架还是存在大量的不足。

   1.HTML文件代码冗余过度

   2.提交全部为GET方式,这使得密码等传输极度不安全

   3.原生SQL语句操纵数据库,开发效率偏低

   4.路由的URL解析太过死板,不能灵活解析

   这些不足点在Django框架中都会有非常好的解决方案,因此Django框架是学习PythonWeb的首选。

   总之前后端交互的大体流程就是这样,前端给请求路径,后端根据路径查询数据库中数据并进行处理后返回HTML文档再由模板语言进行解析(前后端不分离),最终呈现出一个完整的动态页面。

   当然还有很多知识点没有涉及到,如cookieajax,权限管理等等,这些都会在之后慢慢做介绍。

Python 利用三个简易模块熟悉前后端交互流程的更多相关文章

  1. Python Flask高级编程之RESTFul API前后端分离精讲 (网盘免费分享)

    Python Flask高级编程之RESTFul API前后端分离精讲 (免费分享)  点击链接或搜索QQ号直接加群获取其它资料: 链接:https://pan.baidu.com/s/12eKrJK ...

  2. Vue-CLI项目-axios模块前后端交互(类似ajax提交)

    08.31自我总结 Vue-CLI项目-axios前后端交互 一.模块的安装 npm install axios --save #--save可以不用写 二.配置main.js import axio ...

  3. 三、vue前后端交互(轻松入门vue)

    轻松入门vue系列 Vue前后端交互 六.Vue前后端交互 1. 前后端交互模式 2. Promise的相关概念和用法 Promise基本用法 then参数中的函数返回值 基于Promise处理多个A ...

  4. Servlet实现前后端交互的原理及过程解析

    在日常调试项目时,总是利用tomcat去启动项目,并进行前后端联调,但对于前后端的请求响应的交互原理及过程并不是特别清晰. 为什么在前端发出相应请求,就能跳转到后端通过程序得到结果再响应到前端页面呢? ...

  5. Node之简单的前后端交互

    node是前端必学的一门技能,我们都知道node是用的js做后端,在学习node之前我们有必要明白node是如何实现前后端交互的. 这里写了一个简单的通过原生ajax与node实现的一个交互,刚刚学n ...

  6. Django之META与前后端交互

    Django之META与前后端交互 1 提交表单之GET 前端提交数据与发送 1)提交表单数据 2)提交JSON数据 后端的数据接收与响应 1)接收GET请求数据 2)接收POST请求数据 3)响应请 ...

  7. 微信小程序 + thinkjs + mongoDB 实现简单的前后端交互

    说明:这段时间跟老师学习了一下mongodb数据库,这次也是第一次搭建后台服务,出了不少差错,特此来复盘一下,非常感谢对我提供帮助的同学~ 一.使用 thinkjs + mongodb 创建后台服务 ...

  8. Node.js实现前后端交互——用户注册

    我之前写过一篇关于使用Node.js作为后端实现用户登陆的功能,现在再写一下node.js做后端实现简单的用户注册实例吧.另外需要说的是,上次有大佬提醒需要加密数据传输,不应该使用明文传输用户信息.在 ...

  9. 【开源.NET】 轻量级内容管理框架Grissom.CMS(第二篇前后端交互数据结构分析)

    这是 CMS 框架系列文章的第二篇,第一篇开源了该框架的代码和简要介绍了框架的目的.作用和思想,这篇主要解析如何把sql 转成标准 xml 配置文件和把前端post的增删改数据规范成方便后台解析的结构 ...

随机推荐

  1. python6.1创建类

    class Dog(object): type1="宠物"#类变量 #初始化方法 def __init__(self,name,age,color): self.name=name ...

  2. 牛!Python 也能实现图像姿态识别溺水行为了!

    作者 | 李秋键 责编 | Carol 封图 | CSDN 下载自视觉中国 众所周知随着人工智能智能的发展,人工智能的落地项目也在变得越来越多,尤其是计算机视觉方面. 很多人学习python,不知道从 ...

  3. MYSQL 按某个字段分组,然后取每组前3条记录

    先初始化一些数据,表名为 test ,字段及数据为: SQL执行结果为:每个 uid  都只有 3 条记录.   SQL语句为: SELECT   * FROM   test main WHERE   ...

  4. JS 模仿京东键盘输入内容

    css代码 .search { width: 300px; height: 80px; margin: 0 auto; position: relative; } .con { display: no ...

  5. VSFTP问题解决

    支持 root 登录 在 /etc/vsftpd/{ftpusers,user_list} 中注释掉 root 添加 allow_writeable_chroot=YES, 允许在只读文件登录, 否则 ...

  6. tableau用户留存分析

    1.数据源 这是个母婴产品的购买流水数据 2.数据处理 字段拆分.创建购买点会员生命周期 3.分析不同省份的留存率情况 根据第12个月的留存率对省市进行分组 实际业务中也可以通过类似的方法对用户年龄组 ...

  7. C#LeetCode刷题之#441-排列硬币(Arranging Coins)

    问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/3995 访问. 你总共有 n 枚硬币,你需要将它们摆成一个阶梯形状 ...

  8. 使用BERT进行情感分类预测及代码实例

    文章目录 0. BERT介绍 1. BERT配置 1.1. clone BERT 代码 1.2. 数据处理 1.2.1预训练模型 1.2.2数据集 训练集 测试集 开发集 2. 修改代码 2.1 加入 ...

  9. Name jms can't bind to context问题解决

    需要把gis-datamanage包中的配置test改成compile

  10. eric4 中pyqt 字符串 输入 获取

    在eric4中使用pyqt需要注意: 输入 中文 时,前面加 u ,例如: from PyQt4.QtGui import * from PyQt4.QtCore import * QMessageB ...