web框架

 1.基于socket模块创建服务端 通过浏览器进行访问
 2.遵守HTTP超文本传输协议
 3.根据网址后缀不同获取不同的数据内容
 4.请求方式:
  GET:朝服务端获取数据
  POST:向服务端发送数据
 5.从请求数据中获取网址后缀名
  ip_suffix = data.decode('utf8').split(' ')[1]
 6.判断后缀名 然后给不同的后缀名赋予不同的数据内容
 7.代码存在的缺陷:
  7.1 socket代码重复编写
  7.2 请求数据包含内容居多 若想要获取 数据格式处理复杂且重复性太强
  7.3 针对不同的后缀匹配数据内容方式过于low
 8.实操

    import socket

    server = socket.socket()
    server.bind(("127.0.0.1", 8080))
    server.listen(5)
    while True:
        sock, addr = server.accept()
        sock.send(b'HTTP/1.1 200 OK\r\n\r\n')
        data = sock.recv(1024)
        # print(data.decode('utf8'))       # 根据访问地址后加后缀不同 可以根据返回的字符串获取不同的后缀名 赋予不同的数据内容
        ip_suffix = data.decode('utf8').split(' ')[1]  # 接收返回的请求数据进行空格切割并获取访问网址后缀名
        # 判断网址后缀名
        if ip_suffix == '/index':
            sock.send(b'hahaha')
        elif ip_suffix == '/login':
            sock.send(b'xixixi')
        else:
            sock.send(b'123')

基于wsgiref写web框架

 1.解决socket模块编写web框架产生的问题
  1.1 针对socket代码重复编写使用wsgiref模块解决
  1.2 针对请求数据方式过于繁琐采用封装函数解决
  1.3 针对网址后缀获取方式low采用数据与函数对应解决
 2.代码操作:

  2.1 解决1.1问题(利用wsgiref内置模块)
    from wsgiref.simple_server import make_server


    def run(request, response):
        print(request)          # request会将请求数据转换成字典形式
        response("200 ok", [])
        # 判断网址后缀名
        if request['PATH_INFO'] == '/index':
            return [b'hahaha']
        elif request.get('PATH_INFO') == '/login':
            return [b'xixixi']
        else:
            return [b'hello word']


    if __name__ == '__main__':
        server = make_server('127.0.0.1', 8090, run)
        server.serve_forever()
 2.2 解决1.2-1.3问题
    from wsgiref.simple_server import make_server


    def index(request):
        with open(r'02html.html', 'r', encoding='utf8')as f:
        	data = f.read()
    	return data


    def login(request):
        return 'login'


    def error(request):
        return '404'


    suffix_tuple = (('/index', index),
                    ('/login', login),)


    def run(request, response):
        print(request)          # request将请求数据转换成字典形式
        response("200 ok", [])
        # 获取网址后缀
        id_suffix = request.get('PATH_INFO')   # /index
        # 定义变量记录是否已匹配
        func_name = None
        # for循环获取存在的后缀名
        for i in suffix_tuple:
            # 判断输入的后缀名是否存在
            if i[0] == id_suffix:
                func_name = i[1]
                break
        # 判断func_name是否为空
        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', 8090, run)
        server.serve_forever()     # 永久启动
 2.3 代码混乱优化
	根据软件开发目录对代码按照功能进行py文件区分(模块化)
    urls.py        对应关系
    views.py       函数功能
    start.py       启动文件
    templates文件夹 存储html

动静态网页

 1.动态网页:页面上的数据不是全部写死的 有些是动态获取(后端传入)
 2.静态网页:页面上的数据全部都是写死的 更改的话只能修改源代码
 3.实操:后端代码获取当前时间展示到前端页面(字符串替换)

    from wsgiref.simple_server import make_server

    import time


    def get_time(request):
        now_time = time.strftime('%Y-%m-%d %H:%M:%S')
        with open(r'templates/html03.html', 'r', encoding='utf8')as f:
            data = f.read()
        # 将时间嵌入html文件中 用字符串替换
        data = data.replace("时间是治愈一切的良药", now_time)
        return data


    def error(request):
        return '404'


    def login(request):
        return 'hehaha'


    suffix_tuple = (('/get_time', get_time),
                    ('/login', login))


    def fun(request, response):
        # request是k:v键值对
        response('200 ok', [])
        # print(request)
        # 获取输入的网址后缀
        suffix = request.get('PATH_INFO')   # /login
        # 用全局变量记录是否匹配过后缀
        func_name = None
        # for循环获取对应关系中的网址后缀
        for i in suffix_tuple:
            # 判断输入的网址后缀名是否存在
            if i[0] == suffix:
                func_name = i[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', 8090, fun)
        server.serve_forever()

jinja2模块

 1.jinja2模块:能够在html文件中使用类似于后端的语法来操作各种数据类型(第三方模块)
 2.将字典数据传递给html页面并且想要在页面上操作字典数据

  在html页面上使用类似于后端的语法操作数据
    from wsgiref.simple_server import make_server
    from jinja2 import Template


    def my_dict(request):
        info = {'name': 'lili', 'age': 18}
        with open('templates/html04.html', 'r', encoding='utf8')as f:
            data = f.read()
        temp = Template(data)
        res = temp.render(data=info) # 将字典数据传递给html
        return res


    def error(request):
        return '404'


    suffix_tuple = (('/my_dict', my_dict),)


    def fun(request, response):
        response('200 ok', [])
        # 获取输入的网址后缀
        suffix = request.get('PATH_INFO')  # /index
        # 用全局变量记录是否匹配过后缀
        func_name = None
        # for循环获取对应关系中的网址后缀
        for i in suffix_tuple:
            # 判断输入的网址后缀名是否存在
            if i[0] == suffix:
                func_name = i[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', 8090, fun)
        server.serve_forever() 

模板语法

<body>
    <h1>{{data}}}</h1>
    <h1>{{data['name']}}</h1>
    <h1>{{data.get('age')}}</h1>
    <h1>{{data.name}}</h1>
</body>

前端 后端 数据库联动

def get_mysql(request):
    conn = pymysql.connect(
        host='127.0.0.1',
        port=3306,
        user='root',
        password='1234',
        database='day55',
        charset='utf8',
        autocommit=True
    )
    cursor = conn.cursor(cursor=pymysql.cursors.Dictcursor)
    sql1 = 'select * from html04'
    cursor.execute(sql1)
    user_data = cursor.fetchall()
    with open('templates/html04.html', 'r', encoding='utf8')as f:
        data = f.read()
    temp = Template(data)
    res = temp.render(data=user_data)
    return res

python主流web框架

 1.主流框架:django框架、flask框架、tornado框架、fastapi框架、sanic框架
  django框架:大而全 自身携带的功能非常的多 类似于航空母舰
  缺陷:开发小项目的时候使用该框架有点笨重(大材小用)
  flask框架:小而精 自身携带的功能非常的少 类似于特种兵 主要依赖于第三方模块
  缺陷:受限于第三方模块的开发
  tornado框架:异步非阻塞 该框架快到可以作为游戏服务器
  缺陷:上手难度是三者最高的
  fastapi框架:快速、高效编码、更少的bug、智能、简单、简短
  sanic框架:依托于uvloop、asyncio等事件循环和异步并发模块 旨在提供支持异步高并发请求的 web 服务
 注:框架很多 但是内部逻辑差不多

django框架

版本

 1.版本:1.X 同步
  2.X 同步
  3.X 异步

下载安装

 1.下载:pip install django==2.2.22
 2.启动注意事项
  2.1.计算机名称尽量不要有中文
  2.2.项目中所有的py文件名尽量不要用中文
  2.3.不同版本的python解释器配合不同版本的django 会有一些报错
   仔细查找一下报错信息 里面会提示你是哪个py文件里面的代码出错
   找到那一行代码 把逗号删除即可
   widgets.py 152
  2.4.一个pycharm窗口只允许有一个项目 不要做项目的嵌套
 3.验证django是否下载成功
  cmd终端输入django-admin

基本操作

 1.命令行操作:
  1.1 创建django项目
   django-admin startproject 项目名
  1.2 启动django项目
   先切换到项目目录下:cd项目名
    执行启动目录:python manage.py runserver ip:port(ip与端口不写的话默认为本机 端口8000)
   访问django服务端:浏览器直接访问
  创建app应用:
   django框架类似于空壳子 提供所需资源
   功能 需要通过创建app来划分
  注:django初始项目可以看成是一所大学
  app就相当于是大学里面的各个学院
 2.pycharm操作:
  鼠标点
 注:在启动django项目的时候 一定要确保一个端口只有一个项目

命令行与pycharm操作的区别

 1.命令行不会自动创建templates文件夹
 2.命令行不会在配置文件编写关于templates文件夹的配置
  'DIRS': [os.path.join(BASE_DIR, 'templates')]
 3.pycharm自动创建的第一个应用会自动注册到配置文件中
 4.针对db.sqlite3文件不用去在乎它有没有创建 只要运行了django会自动出来

目录结构

 1.django项目目录

文件夹 文件 用途
项目同名文件夹 init.py 做冷门配置
settings.py 项目配置文件
urls.py 对应关系(如网址后缀与函数名)
wsgi.py django服务 基本不用
manage.py django入口文件
templates html.html 存储项目所需的html文件
应用名文件夹(可多个)
db.sqlite3 自带的小型数据库
init.py 做冷门配置
admin.py django自带的后台管理
apps.py 创建应用之后用于应用的注册
models.py 存储与数据库表相关的类
tests.py 自带的测试文件
views.py 存储业务相关的逻辑代码(函数、类)
migrations文件夹 orm相关(数据库打交道的记录)
urls.py    路由层
views.py   视图层
templates  模板层
models.py  模型层

三板斧

 1.HttpResponse:主要用于直接返回字符串类型的数据
 2.render:主要用于返回html页面 并且支持模板语法
 3.redirect:主要用于页面重定向(如 本来是想要将商品添加购物车 却跳转都登录页面)

 posted on 2022-08-30 23:29  拾荒菇凉  阅读(117)  评论(0)    收藏  举报