Django框架
纯手撸web框架
搭建socket服务端
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( ) )
sock. send( b'HTTP/1.1 200 ok \r\n\r\n' )
data_str = data. decode( 'utf8' )
current_path = data_str. split( ' ' ) [ 1 ]
if current_path == '/register' :
sock. send( b'This is a register function' )
elif current_path == '/login' :
sock. send( b'This is a login function' )
else :
sock. send( b'404 not found' )
总结
http请求方式:
GET
朝服务端索要数据
POST
朝服务端提交数据
上述手撸web框架的缺陷:
1 . socket代码重复编写造轮子
2. 针对请求数据格式的处理复杂且重复
3. 针对不同网址后缀的匹配方式过于low
基于wsgiref模块搭建web框架
wsgiref内部封装了socket代码和对请求数据的处理
from wsgiref. simple_server import make_server
def run ( request, response) :
"""
:param request: 请求相关数据
:param response: 响应相关数据
:return: 返回给客户端展示的数据
"""
response( '200 ok' , [ ] )
return [ b'This is a wsgiref models very good' ]
if __name__ == '__main__' :
server = make_server( '127.0.0.1' , 8080 , run)
"监听本机端口8080,一旦有请求访问,则自定触发run方法的执行,与面向对象中的魔法方法__call__类似"
server. serve_forever( )
代码封装优化
1 . wsgiref模块解决了两个问题
1.1 socket代码重复编写造轮子
1.2 针对请求数据格式的处理复杂且重复
2. 思考如何再次实现根据不同的网址后缀返回不同的内容( 函数化)
先从大字典中查找出记录网址后缀的键值对
2.1 不推荐使用连续的多个if 判断
2.2 针对面条版的代码首先应该考虑封装成函数
from wsgiref. simple_server import make_server
def register ( request) :
return 'register'
def login ( request) :
return 'login'
def error ( request) :
return 'error 404 not found'
urls = (
( '/register' , register) ,
( '/login' , login) ,
)
def run ( request, response) :
"""
:param request: 请求相关数据
:param response: 响应相关数据
:return: 返回给客户端展示的数据
"""
response( '200 ok' , [ ] )
current_path = request. get( "PATH_INFO" )
func_name = None
for url_tuple in urls:
if url_tuple[ 0 ] == current_path:
func_name = url_tuple[ 1 ]
break
if func_name:
res = func_name( request)
else :
res = error( request)
return [ res. encode( 'utf8' ) ]
if __name__ == '__main__' :
server = make_server( '127.0.0.1' , 8080 , run)
"监听本机端口8080,一旦有请求访问,则自定触发run方法的执行,与面向对象中的魔法方法__call__类似"
server. serve_forever( )
3. 根据py文件中功能的不同划分到不同的py文件( 模块化)
urls. py 对应关系
views. py 功能函数
start. py 启动文件
templates文件夹 存储html
views.py
def register ( request) :
return 'register'
def login ( request) :
return 'login'
def index ( request) :
return 'index'
def error ( request) :
return 'error 404 not found'
urls.py
from views import *
urls = (
( '/register' , register) ,
( '/login' , login) ,
( '/index' , index) ,
)
start.py
from wsgiref. simple_server import make_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:
if current_path == url_tuple[ 0 ] :
func_name = url_tuple[ 1 ]
break
if func_name:
res = func_name( request)
else :
res = error( request)
return [ res. encode( 'utf8' ) ]
if __name__ == '__main__' :
server = simple_server. make_server( '127.0.0.1' , 8080 , run)
server. serve_forever( )
总结
拆分后好处在于要想新增一个功能,只需要在views. py中编写函数,urls. py添加对应关系即可
动静态网页
动态网页
页面上的数据不是全部写死的 有些是动态获取( 后端传入)
静态网页
页面上的数据直接写死的 要想改变只能修改源码
实际需求
后端代码获取当前时间 然后让前端页面展示
1. 字符串替换
2. 将字典数据传递给html页面并且想要在页面上操作字典数据
我们无法自己实现>> > : 在html页面上使用类似于后端的语法操作数据
动态页面展示
def get_time ( request) :
import time
current_time = time. strftime( '%Y-%m-%d %H:%M:%S' )
with open ( r'templates/myhtml03.html' , 'r' , encoding= 'utf8' ) as f:
data = f. read( )
data = data. replace( 'hahaha' , current_time)
return data
< !DOCTYPE html>
< html lang= "en" >
< head>
< meta charset= "UTF-8" >
< title> Title< / title>
< script src= "https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js" > < / script>
< link rel= "stylesheet" href= "https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" >
< script src= "https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js" > < / script>
< / head>
< body>
< h1> hahaha< / h1>
< / body>
< / html>
安装jinja2
pip3 install jinja2
jinja2模板语法
jinja2能够让我们在html文件内使用类似于后端的语法来操作各种数据类型
from jinja2 import Template
def get_dict ( request) :
user_dict = { 'name' : 'jason' , 'pwd' : 123 , 'hobby' : [ 'read' , 'run' , 'music' ] }
with open ( r'templates/myhtml04.html' , 'r' , encoding= 'utf8' ) as f:
data = f. read( )
temp = Template( data)
res = temp. render( data= user_dict)
return res
< h1> { { data } } < / h1>
< h1> { { data[ 'name' ] } } < / h1>
< h1> { { data. get( 'pwd' ) } } < / h1>
< h1> { { data. hobby } } < / h1>
前后端与数据库互联实例
数据库层面操作
数据库操作
1. 登录mysql,完成库、表、数据的写入
2. 启动mysql
net start mysql
3. 登录mysql
mysql - uroot - p
4. 创建数据库
create database 库名;
5. 查看数据库
show databases;
6. 切换到指定的库
use 库名;
7. 创建表
create table userinfo( id int primary key auto_increment, name varchar( 32 ) , age int ) ;
8. 查看表
desc userinfo;
9. 写入数据
insert into userinfo( name, age) values( 'jason' , 18 ) , ( 'tony' , 23 ) , ( 'kevin' , 24 ) , ( 'jerry' , 32 ) ;
10. 查看数据
select * from userinfo;
前端页面操作
<! DOCTYPE html >
<! DOCTYPE html >
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< title> Title</ title>
< script src = " https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js" > </ script>
< link rel = " stylesheet" href = " https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" >
< script src = " https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js" > </ script>
</ head>
< body>
< div class = " container" >
< div class = " row" >
< h1 class = " text-center" > 用户信息</ h1>
< div class = " col-md-8 col-md-offset-2" >
< table class = " table table-hover table-striped " >
< thead>
< tr>
< th> 主键</ th>
< th> 姓名</ th>
< th> 年龄</ th>
</ tr>
</ thead>
< tbody>
{% for user in user_data %}
< tr class = " info" >
< td> {{user.id}}</ td>
< td> {{user.name}}</ td>
< td> {{user.age}}</ td>
</ tr>
{% endfor %}
</ tbody>
</ table>
</ div>
</ div>
</ div>
</ body>
</ html>
后端逻辑代码
from jinja2 import Template
import pymysql
def get_mysql ( request) :
conn = pymysql. connect(
host= '127.0.0.1' ,
port= 3306 ,
user= 'root' ,
password= '123456' ,
database= 'day55' ,
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/myhtml04.html' , 'r' , encoding= 'utf8' ) as f:
data = f. read( )
temp = Template( data)
res = temp. render( user_data= user_data)
return res
结果验证
python主流web框架
django
大而全 自带的功能非常的多 但是有时候会略显笨重,类似于'航空母舰'
flask
小而精 自带的功能非常的少 但是第三方模块非常的多,类似于'游骑兵'
flask的第三方模块加到一起甚至比django还多 并且也越来越像django
flask由于过多的依赖于第三方模块 有时候也会受制于第三方模块
tornado
异步非阻塞框架 速度极快 甚至可以用于充当游戏服务器
缺陷: 上手难度是三者最高的
还有一些占比较小 但是也很厉害的框架
fastapi、sanic. . . . . .
"""
框架的核心逻辑几乎是一致的 我们在学习的时候只需要先学会一种
之后就可以触类旁通 但是需要强调的是:千万不用同时学习!!!
"""
django框架版本
版本问题
django3. X: 自带异步功能
django2. X: 默认不支持异步
django1. X: 默认不支持异步
'''
与3.X最主要的区别在于新增了一个异步的功能
'''
django下载及注意事项
1. 下载安装
pip3 install django== 1.11 .11
'''如果之前下载了其他版本不用管 自动替换!!!'''
2. 启动注意事项
1. 计算机名称尽量不要有中文
2. 项目中所有的py文件名尽量不要用中文
3. 不同版本的python解释器配合不同版本的django会有一些报错
启动如果报错,根据提示找到代码,并修改widgets. py文件第152 行源码,删除最后的逗号即可
4. 一个pycharm窗口只允许有一个项目 不要做项目的嵌套
3. 验证django是否下载成功,需要提前配置环境变量,否则会出现报错
cmd终端输入django- admin
django基本使用
命令行操作Django
1. 创建django项目
django- admin startproject 项目名
2. 启动django项目
1. 先切换到项目目录下
cd 项目名
2. 执行启动目录
python38 manage. py runserver ip: port
3. 访问django服务端
浏览器直接访问:http: // 127.0 .0 .1 : 8000 /
4. 创建app应用
"""
django框架类似于是一个空壳子 给你提供所需的资源
至于到底要写哪些功能 需要通过创建app来划分
eg:django初始项目可以看成是一所大学
app就相当于是大学里面的各个学院
"""
python38 manage. py startapp 应用名
"""
在启动django项目的时候 一定要确保一个端口只有一个项目
"""
pycharm操作Django
命令行与pycharm操作的区别
1. 命令行不会自动创建templates文件夹
2. 命令行不会在配置文件编写关于templates文件夹的配置
'DIRS' : [ os. path. join( BASE_DIR, 'templates' ) ]
3 . pycharm自动创建的第一个应用会自动注册到配置文件中
4. 针对db. sqlite3文件不用去在乎它有没有创建 只要运行了django会自动出来
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小白必会三板斧
urls.py
from django. contrib import admin
from django. urls import path
from app01 import views
urlpatterns = [
path( 'admin/' , admin. site. urls) ,
path( 'index/' , views. index) ,
path( 'function/' , views. function) ,
path( 'login/' , views. login) ,
]
view.py
from django. shortcuts import render, HttpResponse, redirect
HttpResponse
主要用于直接返回字符串类型的数据
def index ( request) :
return HttpResponse( '山重水复疑无路,柳暗花明又一村' )
render
主要用于返回html页面 并且支持模板语法
def function ( request) :
user_dict = { 'name' : 'jason' , 'pwd' : 123 }
return render( request, 'myhtml.html' , { 'data' : user_dict} )
redirect
主要用于页面重定向,如下所示:跳转页面到百度,地址可以自定义
def login ( request) :
return redirect( 'https://www.baidu.com' )
myhtml
<! DOCTYPE html >
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< title> Title</ title>
< script src = " https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js" > </ script>
< link rel = " stylesheet" href = " https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" >
< script src = " https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js" > </ script>
</ head>
< body>
< h1 class = " text-center" > This is a Django2.2.22 version welcome to Django</ h1>
< h1> {{ data }}</ h1>
< h1> {{ data.name }}</ h1>
< h1> {{ data.pwd }}</ h1>
</ body>
</ html>
基于Django获取数据库信息并展示到前端
urls.py
"""day55_Django URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/2.2/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django. contrib import admin
from django. urls import path
from app01 import views
urlpatterns = [
path( 'admin/' , admin. site. urls) ,
path( 'index/' , views. index) ,
path( 'function/' , views. function) ,
path( 'login/' , views. login) ,
path( 'mysql/' , views. mysql) ,
]
views.py
from django. shortcuts import render, HttpResponse, redirect
def index ( request) :
return HttpResponse( '山重水复疑无路,柳暗花明又一村' )
def function ( request) :
user_dict = { 'name' : 'jason' , 'pwd' : 123 }
return render( request, 'myhtml.html' , { 'data' : user_dict} )
def login ( request) :
return redirect( 'mysql' )
from jinja2 import Template
import pymysql
def mysql ( request) :
conn = pymysql. connect(
host= '127.0.0.1' ,
port= 3306 ,
user= 'root' ,
password= '123456' ,
database= 'day55' ,
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/myhtml.html' , 'r' , encoding= 'utf8' ) as f:
data = f. read( )
temp = Template( data)
res = temp. render( user_data= user_data)
return HttpResponse( res)
myhtml
<! DOCTYPE html >
<! DOCTYPE html >
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< title> Title</ title>
< script src = " https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js" > </ script>
< link rel = " stylesheet" href = " https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" >
< script src = " https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js" > </ script>
</ head>
< body>
< div class = " container" >
< div class = " row" >
< h1 class = " text-center" > 用户信息</ h1>
< div class = " col-md-8 col-md-offset-2" >
< table class = " table table-hover table-striped " >
< thead>
< tr>
< th> 主键</ th>
< th> 姓名</ th>
< th> 年龄</ th>
</ tr>
</ thead>
< tbody>
{% for user in user_data %}
< tr class = " info" >
< td> {{user.id}}</ td>
< td> {{user.name}}</ td>
< td> {{user.age}}</ td>
</ tr>
{% endfor %}
</ tbody>
</ table>
</ div>
</ div>
</ div>
</ body>
</ html>
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现