Django框架简介
目录
简易web框架
# web框架
将前端、数据库整合到一起的基于互联网传输的python代码
web框架也可以简单的理解为是软件开发架构里面的'服务端'
# 搭建简易版本服务端
socket模块
# 遵循HTTP协议
四大特性、数据格式、响应状态码
# 基于不同的后缀响应不同的内容
如何获取用户输入的url后缀>>>:HTTP请求数据
/favicon.ico直接忽略
利用字符串切割和索引取值获取相应数据
import socket
server = socket.socket()
server.bind(('127.0.0.1', 8088))
server.listen(5)
while True:
sock, addr = server.accept()
data = sock.recv(1024)
# 将请求相关数据先转成字符串
data_str = data.decode('utf8')
sock.send(b'HTTP1.1 200 OK\r\n\r\n')
# 然后去字符串中截取出我们需要的内容
current_path = data_str.split(' ')[1]
# 根据后缀的不同返回不同的内容
if current_path == '/login':
sock.send(b'hello, this is login view')
elif current_path == '/register':
sock.send(b'hello, this is register view')
elif current_path == '/home':
sock.send(b'hello, welcome to home page')
else:
sock.send(b'404 error')
# 上述简易框架缺陷:
1.服务端起始代码重复
2.针对HTTP请求数据没有高效的处理方式
3.并发量问题
基于wsgiref模块
# 利用模块搭建服务端
# 利用模块处理好的HTTP字典数据编写业务
查找浏览器url后缀对象的键值对数据
from wsgiref import simple_server
def run(request, response):
"""
参数含义
:param request: 请求相关的数据
:param response: 响应相关的数据
:param return: 返回给客户端的展示数据
"""
print(request) # 字典类型的数据
response('200 OK', [])
current_path = request.get("PATH_INFO")
if current_path == '/login':
return [b'hello login html']
elif current_path == '/register':
return [b'hello register html']
elif current_path == '/home':
return [b'hello, welcome to home page']
return [b'404 error']
if __name__ == '__main__':
server = simple_server.make_server('127.0.0.1', 8086, run) # 一直监听本机8086端口,一旦有请求访问,自动执行run方法
server.serve_forever()
优化措施
# 需要优化处理两个问题
1.如果网站很多,需要添加的elif语句太多影响扩展性
2.每个分支下的功能根据业务逻辑的不同可能会比较复杂
解决办法:将匹配和功能封装成 元组和函数
# 所有的代码全部放在一个py文件过于冗余,后期管理维护困难的问题
解决办法:根据功能的不同拆分成不同的py文件
urls.py 对应关系的存储
views.py 业务逻辑的编写
# 后面新增功能,只需要在urls.py中添加对应关系,在view.py中编写函数
"templates文件夹"
业务函数的代码中,可有可能频繁地使用到不同的html页面;单独开设一个文件夹存储所有的html文件可以避免文件类型的混乱。
templates文件夹 作用:存储项目所需的html文件
"static文件夹"
项目中的html文件可能需要用到css、js、第三方框架文件html。而css、js、第三方框架代码封装好的不经常修改的文件,所以可以统一存放在一个文件夹下
static文件夹 作用:存储项目所需的'静态文件'
点击查看启动代码
from wsgiref import simple_server
from urls import urls
from views import error
def run(request, response):
response('200 OK', [])
current_path = request.get("PATH_INFO")
func_name = None
for url_tuple in urls: # ('/register', register)
if current_path == url_tuple[0]:
# 先获取对应的函数名
func_name = url_tuple[1]
break
# for循环运行完毕之后,func_name也有可能是None
if func_name:
res = func_name(request)
else:
res = error(request) # 将request也传给函数,用于后续数据的获取
return [res.encode('utf8')]
if __name__ == '__main__':
server = simple_server.make_server('127.0.0.1', 8080, run)
'''一直监听本机8080端口,一旦有请求访问,自动执行run方法'''
server.serve_forever()
点击查看view.py代码
# 功能函数
def register(request):
return 'register'
def login(request):
return 'login'
def index(request):
return 'index'
def error(request):
with open(r'templates/error.html', 'r', encoding='utf8') as f:
return f.read()
def func(request):
with open(r'templates/func.html', 'r', encoding='utf8') as f:
return f.read()
def get_time(request):
# 1.获取当前时间
import time
c_time = time.strftime('%Y-%m-%d %X')
# 2.读取html文件
with open(r'templates/get_time.html', 'r', encoding='utf8') as f:
data = f.read()
# 3.字符串替换
new_data = data.replace('qaq', c_time)
return new_data
from jinja2 import Template
def get_dict(request):
user_dict = {'name': 'peter', 'pwd': 999, 'hobby': 'swim'}
new_list = [111, 222, 333, 444, 555, 666, 777, 888, 999]
with open(r'templates/get_dict.html', 'r', encoding='utf8') as f:
data = f.read()
temp_obj = Template(data)
res = temp_obj.render({'user': user_dict, 'new_list': new_list})
# 给页面传递一个变量名是user 值是user_dict对应的值的数据
return res
import pymysql
def get_db(request):
conn = pymysql.connect(
host='127.0.0.1',
port=3306,
user='root',
password='qwer9999',
db='day49',
charset='utf8',
autocommit=True
)
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
sql = 'select * from userinfo'
cursor.execute(sql)
data_list = cursor.fetchall()
with open(r'templates/get_db.html', 'r', encoding='utf8') as f:
data = f.read()
temp_obj = Template(data)
res = temp_obj.render({'data_list': data_list})
return res
点击查看urls.py代码
from views import *
# 后缀匹配
urls = (
('/register', register),
('/login', login),
('/index', index),
('/func', func),
('/get_time', get_time),
('/get_dict', get_dict),
('/get_db', get_db)
)
动静态网页
# 静态网页
页面上的数据是提前定义好的,基本上不会改动
# 动态网页
页面上的数据是通过代码动态获取的,实时更新
eg:
1.页面上展示当前时间(后端获取传递给前端界面)
2.页面上展示数据库数据(后端链接数据库查询数据再传递给页面)
# 案例: 页面上展示当前时间
def get_time(request):
# 1.获取当前时间
import time
c_time = time.strftime('%Y-%m-%d %X')
# 2.读取html文件
with open(r'templates/get_time.html','r',encoding='utf8') as f:
data = f.read()
# 3.字符串替换
new_data = data.replace('asdaksdjal',c_time)
return new_data
jinja2模块
# 第三方模块
安装:pip3 install jinja2
# 功能介绍
在编写前后端不分离项目的时候,可以使用该模块提供的模板语法简单快速的在html页面是使用类似于后端的代码语法操作数据
# 模板语法
temp_obj.render({'user':user_dict,'new_list':new_list})
<p>{{ user }}</p>
<p>{{ user.name }}</p>
<p>{{ user['pwd'] }}</p>
<p>{{ user.get('age') }}</p>
{% for i in new_list %}
<span>元素:{{ i }}</span>
{% endfor %}
python主流web框架
django
大而全,自带的功能非常的多。但用在比较小的项目会略显笨重
flask
小而精,自带的功能比较少,但第三方模块非常的多
flask的第三方模块加到一起甚至比django还多。并且也越来越像django
flask因为过多的依赖于第三方模块,有时候也会受制于第三方模块
tornado
异步非阻塞框架,速度极快,甚至可以用做游戏服务器
django框架简介
# 版本
django3.X:默认支持异步功能
django2.X:默认不支持异步
django1.X:默认不支持异步
# 发布时间
django1.11.X LTS 2018年发布
django2.2.X LTS 2020年发布
# 启动问题
django启动可能报错的原因
1.计算机名称不能含有中文
直接修改即可
2.不同版本的解释器可能会报错
找到报错信息的最后一行提示对应的代码,删除源文件逗号即可
3.项目中所有的文件名称建议使用英文
4.一个pycharm窗口尽量就是一个完整的项目,不要嵌套
# 下载(cmd窗口)
pip3 install django==1.11.xx
django基本使用
# 验证是否下载成功
cmd窗口直接输入django-admin有反应就是下载成功
# 命令操作django
1.创建django项目
django-admin startproject 项目名(mysite)
2.启动django项目
cd 项目名(mysite)
python3 manage.py runserver IP:PORT
3.创建app应用
python3 manage.py startapp 应用名(app01)
注意:命令行无法自动创建模板文件夹 需要自己执行命令创建
# pycharm操作django
1.new project
选择django,填写应用即可
提示:pycharm默认会自动创建模板文件夹并提供创建一个app的功能
2.创建更多的app
tools
run manage.py task 命令自动提示
3.启动项目
直接点击绿色箭头
修改端口号 edit configurations
django主要文件介绍
# day50项目文件名
day50 项目文件同名文件夹
settings.py 项目配置文件
urls.py 路由层
# manage.py
django入口文件,很多命令都需要manage.py支持
# db.sqlite3
django启动之后才会生成的文件 其实就是django自带的小型数据库
# templates文件夹
模板层
# app01应用文件夹
migrations文件夹 数据迁移记录
admin.py django自带的后台管理
apps.py 用于app的注册
models.py 专门用于操作数据库
views.py 视图层
# 创建应用之后一定要去配置文件中注册才能生效
'app01.apps.App01Config' 完整语法
'app01' 简写语法