手搓web框架以及Django简介
手搓简易web框架
web框架可以简单的理解为是基于互联网的web服务端 >>>:socket服务端
1.手搓一个服务端代码
import socket
server = socket.socket()
server.bind(('127.0.0.1', 8080))
server.listen(5)
sock, address = server.accept()
data = sock.recv(1024)
sock.send(b'hello world')
2.我们会发现其实在浏览器页面打不开我们的客户端那么我们就需要注意HTTP协议,来接入网络
sock.send(b'HTTP/1.1 200 ok\r\n\r\n')
3.接下来我们就想别的客户端只要是网址后缀不同就能够展示出不同的页面和内容,那么我们也想要这种功能
4.寻找到我们服务端想要请求的方式然后我们给它展示别的东西
GET
朝服务端发送请求,请求数据
POST
朝服务端提交请求,服务端接受并给出反馈
5.我们从请求的数据格式中筛选出用户输入的网址后缀,然后利用这个网址后缀给客户端展示出该网址后缀所对应的信息,那么我们就实现了一个简易的web框架
import socket
server = socket.socket()
server.bind(('127.0.0.1', 8080))
server.listen(5)
while True:
sock, address = server.accept()
data = sock.recv(1024)
print(data.decode('utf-8'))
sock.send(b'HTTP/1.1 200 ok\r\n\r\nhafbuhiojkjg')
target_url = data.decode('utf-8').split(' ')[1]
if target_url == '/index':
sock.send(b'index view')
elif target_url == '/login':
sock.send(b'login view')
elif target_url == '/reg':
sock.send(b'reg view')
else:
sock.send(b'404 Error')
6.上方建议web框架的缺陷
1.socket代码重复编写造轮子,也就是我们每创建一个服务端那么就会写一次这个固定格式的服务端代码。
2.针对请求数据格式的处理复杂且重复
3.针对不同网址后缀的匹配方法过于低级,一点逼格都没有不符合我们的职业,并且写成那样会遭受鄙视
基于wsgierf模块搓框架
1.wsgiref内部封装了socket代码和对请求数据的处理,那么我们就可以解决上方我们所遇到的前两个缺陷
1.socket代码冗余,过程重复
2.针对请求数据格式的处理复杂且重复
from wsgiref.simple_server import make_server
def run(request,response):
"""
:param request: 请求数据
:param response: 响应数据
:return: 返回给客户端的数据
"""
print(request) # 自动请求数据去哪不处理成字典的K:V键值对的形式
response('200 OK',[]) # 固定的代码
return [b'hello world'] # 返回我们想要返回的值
if __name__ == '__main__': # 用来帮忙验证我们所处于哪个文件夹,如果是执行文件那么就会是__main__
server = make_server('127.0.0.1',8080,run) # 任何访问127.0.0.1:8080的请求都会给第三个参数加括号调用
server.serve_forever() # 字面意思,永远为启动状态
2.思考如何利用这个再次实现根据不同的网址后缀返回不同的内容(函数化)
先从大字典中查找出记录网址后缀的键值对
注意事项:
1.不推荐使用连续多个if判断,当我们去公司的时候使用if判断最好不要超过三层。
def run(request,response):
"""
:param request: 请求数据
:param response: 响应数据
:return: 返回给客户端的数据
"""
print(request) # 自动请求数据去哪不处理成字典的K:V键值对的形式
response('200 OK',[]) # 固定的代码
target_path = request.get('PATH_INFO')
func_name = None
for url_tuple in urls:
if url_tuple[0] == target_path:
func_name = url_tuple[1]
break
if func_name:
res = func_name(request)
else:
res = error(request)
return [res.encode('utf-8')]
2.针对面条拌的代码首先要考虑的就是封装成函数,然后将函数封装成模块,由模块导向面向对象class等
def index(request):
return 'index'
def login(request):
return 'login'
def register(request):
return 'register'
def error(request):
return '404 error'
urls = (
('/index',index),
('/login',login),
('/register',register),
('/error',error)
)
3.根据py文件中功能不同划分到不同的py文件中(模块化)
urls.py 对应关系
views.py 功能函数
start.py 启动文件
templates文件夹 存储html文件
动静态页面
- 页面概念
- 动态页面
- 页面上的数据不是全部都写死的,有些事动态获取(后端获取)的,是可以根据实时改变的叫做动态页面,例如时间
- 静态页面
- 页面上的市局直接被写死了,想要更爱只能通过改变源码才可以的页面叫做静态页面
def get_time(request): # 创建函数并导入请求体
import time # 导入模块
ctime = time.strftime('%Y-%m-%d %H:%M:%S') # 使用字符串形式来获取现在时间
with open(r'templates/01.html','r',encoding='utf-8') as f: # 读取文件
data = f.read() # 读取文件
data = data.replace('热死了',ctime) # 更改HTML文件中的数据
return data # 返回我们修改后的数据
- 实际需求
- 厚度那代码获取当前时间,然后让前端页面进行展示当前时间,这种情况的需求就叫做实际需求
- 字符串的替换
- 将字典数据传递给html页面并且想要在页面上操作字典的数据,通过我们自己的话很难实现,所以我们就需要在页面上使用类似后端的语法来操作数据
- 我们写python代码如果碰到了一些难以解决的问题或者说很麻烦的那么我们首先去网上寻找有没有人做过类似的事情然后我们去寻找他的第三方模块(95%)的问题都可以被找到
jinja2模板语法
jianja2能够让我们在html文件内使用类似于后端的语法来操作各种数据类型
pip3 install jinja2
def get_dict(request): #创建一个函数并且导入请求体
from jinja2 import Template # 导入jinja2模块
user_dict = {'name':'kunkun','age':21,'hobby':['singer','jump','rap','basketball']} # 创建一个用户字典
with open(r'templates/01.html','r',encoding='utf-8') as f: # 读取文件
data = f.read() # 获取数据
temp = Template(data) # 重新赋值
res = temp.render(data=user_dict) # 将字典传递给html页面页面上同过data即可获取(data仅仅是一个变量名)
return res
前端、后端、数据库三者联动
1.后端内容:
def get_mysql(request):
import pymysql
conn = pymysql.connect(
host='127.0.0.1',
port=3306,
user='root',
password='',
database='djangoday1',
charset='utf8',
autocommit=True
)
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
sql = 'select * from userinfo'
cursor.execute(sql)
user_data = cursor.fetchall()
with open(r'templates/03.html','r',encoding='utf-8') as f:
data = f.read()
temp = Template(data)
res = temp.render(user_data=user_data)
return res
2.html页面内容
<div class="container">
<div class="row">
<h1 class="text-center">数据展示</h1>
<div class="col-md-8 col-md-offset-2"></div>
<table class="table table-hover table-striped">
<thead>
<tr>
<th>主键</th>
<th>姓名</th>
<th>年龄</th>
</tr>
</thead>
<tbody>
{% for user in user_data %}
<tr>
<td>{{ user.id }}</td>
<td>{{ user.name }}</td>
<td>{{ user.age }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
python主流web框架
Django框架
大而全 自身携带的功能非常齐全,类似于航空母舰
缺陷:开发小项目时使用该框架有点笨重(大材小用,所以我们应该做到因材施教)
flask框架
小而精 自身携带的功能非常的少,就像是特种兵,主要依赖于第三方模块
缺陷:受限于第三方模块的开发(成也萧何败也萧何)
tornado框架
异步非阻塞 该框架快到可以作为游戏服务器
缺陷:上手难度高,但是非常强大
fastapi框架 最近流行的
sanic框架 最近流行的
Django版本及安装问题
1.Django版本问题
1.x:同步 常使用或者在维护版本: 1.11
2.x:同步 常使用或者在维护版本: 2.2
3.x:异步 常使用或者在维护版本: 3.2
2.启动注意事项
1.计算机名称中尽量不要有中文提示(可在设置中查找)
2.项目中的文件名称尽量不要使用中文
3.不同版本的python解释器配合不同的版本的Django会有一些报错(仔细寻找报错信息,会显示是哪个py文件出现问题,我们根据提示去修改报错,一般为 widgets.py 152行 删除哪个逗号即可)
4.一个python窗口只能允许有一个项目,如果打开两个那么默认只是第一个打开,因为端口号只有一个(解决思路更改端口号)
3.验证Django是否下载成功
cmd终端输入django_admin
Django基本操作
命令行操作
1.创建Django项目
django_admin startproject 项目名(old boy 默认暗号名:app01)
2.启动Django项目
1.先切换到项目目录下
cd 项目名
2.执行启动目录
python38 manage.py runserver ip:port
3.访问Django服务端
浏览器直接访问即可
4.创建app应用
Django框架类似于一个空壳子 给你提供所需要的资源
如何武装或者装修这个空壳子,修改书写哪些内容,就需要通过创建app来划分
也可以把Django看做一所大学,app就像里面的各个学院
python38 manage.py startapp 应用名
5.pycharm操作
鼠标点击即可
命令行与pycharm创建差异
1.命令行不会自动创建templates文件夹
2.命令行不会在配置文件编写关于templates文件夹配置
'DIRS':[os.path.join(BASE_DIR,'templates')]
3.pycharm自动创建的第一个应用汇自动注册到配置文件夹中
4.针对db.sqlite3文件不用去在乎它有没有创建,只要运行率Django会自动出来
Django目录结构
项目目录 |
名称 |
功能 |
项目同名目录 |
init.py |
很少用,主要是用作一些冷门配置 |
|
settings.py |
项目配置文件 |
|
urls.py |
对应关系 |
|
wsgi.py |
Django服务 基本不用 |
|
manage.py |
Django入口文件 |
|
templates |
存储项目所需的HTML文件 |
应用名文件夹(可以有多个) |
migrations |
ORM相关(数据库打交道的记录) |
|
init.py |
很少使用,还是做冷门配置 |
|
admin.py |
Django自带的后台管理 |
|
apps.py |
创建应用之后用于应用的注册 |
|
models.py |
存储与数据库表相关的类 |
|
tests.py |
自带的测试文件 |
|
views.py |
存储业务相关的逻辑代码(函数、类) |
|
db.sqlite3 |
自带的小型数据库 |
大纲 |
urls.py |
路由层 |
|
views.py |
视图层 |
|
templates |
模板层 |
|
models.py |
模型层 |
Django小白必会三板斧
HttpResponse
主要用于直接返回字符串类型的数据
render
主要用于返回html页面,并且支持模板语法
redirect
主要用于页面重定向,也就是本来是去这个页面转而给它自动跳往我们指定的页面