仿Django框架-基于wsgiref模块和jinja2模块写一个简单的框架 主流框架简介 动静态网页 Python虚拟环境

Posted 每天的学习的知识都要记录!

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了仿Django框架-基于wsgiref模块和jinja2模块写一个简单的框架 主流框架简介 动静态网页 Python虚拟环境相关的知识,希望对你有一定的参考价值。

目录

仿Django框架-基于wsgiref模块和jinja2模块写一个简单的框架

一、前期需要的了解背景知识

  • web框架的本质
    • 理解1:连接前端与数据库的中间介质
    • 理解2:socket服务端
  • 手写web框架的大概思路
    1.编写socket服务端代码
    2.浏览器访问响应无效>>>:HTTP协议
    3.根据网址后缀的不同获取不同的页面内容
    4.想办法获取到用户输入的后缀>>>:请求数据
    5.请求首行>>>GET /login HTTP/1.1
  •  GET请求   朝别人索要数据
    
  •  POST请求  朝别人提交数据
    

    6.处理请求数据获取网址后缀
    问题:
    1.socket代码过于重复
    2.针对请求数据处理繁琐
    3.后缀匹配逻辑过于LowB

基于socket模块写的服务端

import socket


server = socket.socket()  # TCP UDP
server.bind((\'127.0.0.1\', 8080))  # IP PORT
server.listen(5)  # 半连接池


while True:
    sock, address = server.accept()  # 等待连接
    data = sock.recv(1024)  # 字节(bytes)
    # print(data.decode(\'utf8\'))  # 解码打印
    sock.send(b\'HTTP/1.1 200 OK\\r\\n\\r\\n\')
    data_str = data.decode(\'utf8\')  # 先转换成字符串
    target_url = data_str.split(\' \')[1]  # 按照空格切割字符串并取索引1对应的数据
    # print(target_url)  # /index /login /reg
    if target_url == \'/index\':
        # sock.send(b\'index page\')
        with open(r\'myhtml01.html\',\'rb\') as f:
            sock.send(f.read())
    elif target_url == \'/login\':
        sock.send(b\'login page\')
    else:
        sock.send(b\'home page!\')

二、基于wsgiref模块做优化

  • wsgiref功能简单介绍
    内置模块 很多web框架底层使用的模块

    • 功能1:封装了socket代码
    • 功能2:处理了请求数据
      1.固定代码启动服务端
      2.查看处理之后的request大字典
      3.根据不同的网址后缀返回不同的内容>>>:研究大字典键值对
      4.立刻解决上述纯手撸的两个问题
      5.针对最后一个问题代码如何优化
  • 代码编写

from wsgiref.simple_server import make_server


def run(request, response):
    """
    :param request: 请求相关数据
    :param response: 响应相关数据
    :return: 返回给客户端的真实数据
    """
    response(\'200 OK\', [])  # 固定格式 不用管它
    # print(request)  是一个处理之后的大字典
    path_info = request.get(\'PATH_INFO\')
    if path_info == \'/index\':
        return [b\'index\']
    elif path_info == \'/login\':
        return [b\'login\']
    return [b\'hello wsgiref module\']


if __name__ == \'__main__\':
    server = make_server(\'127.0.0.1\', 8080, run)  # 实时监听127.0.0.1:8080 一旦有请求过来自动给第三个参数加括号并传参数调用
    server.serve_forever()  # 启动服务端

三、代码封装优化

1.网址后缀的匹配问题
2.每个后缀匹配成功后执行的代码有多有少,所以可以分成面条版 函数版 模块版
3.将分支的代码封装成一个个函数
4.将网址后缀与函数名做对应关系
5.获取网址后缀循环匹配
6.如果想新增功能只需要先写函数再添加一个对应关系即可
7.根据不同的功能拆分成不同的py文件

  •   views.py		存储核心业务逻辑(功能函数)
    
  •   urls.py			存储网址后缀与函数名对应关系
    
  •   templates目录	   存储html页面文件
    

8.为了使函数体代码中业务逻辑有更多的数据可用,将request大字典转手传给这个函数(可用不用但是不能没有)

四、jinja2模块

  • 命令行下载
    pip3 install jinja2

  • 使用

from jinja2 import Template


def get_dict_func(request):
    user_dict = \'name\': \'jason\', \'age\': 18, \'person_list\': [\'阿珍\', \'阿强\', \'阿香\', \'阿红\']
    with open(r\'templates/get_dict_page.html\', \'r\', encoding=\'utf8\') as f:
        data = f.read()
    temp_obj = Template(data)  # 将页面数据交给模板处理
    res = temp_obj.render(\'d1\': user_dict)  # 给页面传了一个 变量名是d1值是字典数据的数据
    return res

<p> d1 </p>
<p> d1.name </p>
<p> d1[\'age\'] </p>
<p> d1.get(\'person_list\') </p>

五、动静态网页

  •   动态网页:页面数据来源于后端
    
  •   静态网页:页面数据直接写死的,就是我们常见的:CSS文件、JS文件、img文件、我们的第三方前端框架:bootstrap相关的
    
  • 了解概念
    1.访问某个网址后缀 后端代码获取当前时间 并将该时间传到html文件上再返回给浏览器展示给用户看
    读取html内容(字符串类型) 然后利用字符串替换 最后再返回给浏览器
    2.将字典传递给页面内容 并且在页面上还可以通过类似于后端的操作方式操作该数据
    模板语法>>>:jinja2模块

六、Python主流web框架

  • django

	大而全 自身自带的功能组件非常的多 类似于航空母舰 		
  • flask

	小而精 自身自带的功能组件非常的少 类似于游骑兵,几乎所有的功能都需要依赖于第三方模块 
  • tornado

	异步非阻塞 速度极快效率极高甚至可以充当游戏服务端

ps:还有sanic、fastapi...
提示:作为小白的你 初学阶段不要混着学 很容易走火入魔

七、虚拟环境

  • 为什么要使用虚拟环境?
    项目1需要使用:django1.11 python38
    项目2需要使用:django2.22 pymysql requests python38
    项目3需要使用:django3.22 request_html flask urllib3 python38

    实际开发项目中我们只会给项目配备所需的环境,不需要的一概不配!!!
    虚拟环境:能够针对相同版本的解释器创建多个分身 每个分身可以有自己独立的环境

  • 创建虚拟环境:(每创建一个虚拟环境就相当于重新下载了一个全新的解释器)
    方式一:pycharm创建

方式二:命令行的方式创建


	python -m venv pyvenv38

PS:python命令此处不支持多版本共存的操作 python27 python36 python38,环境变量中谁靠前就用哪个解释器版本
激活:activate
关闭:deactivate(后面会详细解释)

Django初窥

Django初窥

软件开发架构C/S

HTTP协议

四大特性

  1. 基于tcp/ip作用与应用层之上的协议
  2. 基于请求响应
  3. 无连接 websocket长连接
  4. 无状态 cookie session token。。

数据格式

请求格式

请求首行

请求头

/r/n

请求体

响应状态

用数字表示一串语言解释

web框架简易版

import socket

server=socket.socket()
server.bind(('127.0.0.1',8080))
server.lisetn(5)

while True:
    conn,addr=server.accept()
    conn.send(b'HTTP/1.1 200 OK

')
    data_str=data.decode('utf-8')
    current_path=data_str.split('
')[0].split(' ')[1]
    if current_path=='/index':
        with open(r'123.html','rb') as f:
            conn.send(f.read())
    elif current_path == '/login':
        conn.send(b'login')
    else:
        conn.send(b'404 error')
    conn.close()
            
            

基于wsgiref模块

基于第三方模块帮你撸

views.py:里面放的是函数,我们管这些函数叫视图函数 视图层

urls.py:里面放的是路由(后缀)与视图函数的对应关系 路由层

templates:里面放的全是html文件

from wsgiref.simple_server import make_server
from urls import urls
from views import *
def run(env,response)
     """
    :param env: 请求相关的所有数据 将http数据全部提前处理成了字典的形式 供调用者使用
    :param response: 响应相关的所有数据
    :return: 给前端真正的数据
    """
    response('200 OK',(['xxx','gg'])
    current_path=env.get('PATH_INFO')
    func=None
    for url in urls: # url =  ('/login',login)  ('/index',index)
        if current_path==url[0]:
             func=url[1]
             break
    if func:
       res=func(env)
    else:
       res=error(env)
             
    return [res.encode('utf-8'),]
             

jinjia2模块

专门用来处理后端数据与html页面的交互

模板语法(极其贴近python后端语法)

让你能够再html页面上也能够用后端python语法来操作后端传递过来的数据

<p>{{ userDic }}</p>
<p>{{ userDic.username }}</p>
<p>{{ userDic['age'] }}</p>
<p>{{ userDic.get('hobby') }}</p>
<p>{{ userDic.get('hobby').0 }}</p>
<p>{{ userDic.get('hobby').1 }}</p>
<p>{{ userDic.get('hobby').2 }}</p>

{% for user_dic in user_list %}
<tr>
    <td>{{ user_dic.id }}</td>
    <td>{{ user_dic.username }}</td>
    <td>{{ user_dic.password }}</td>
</tr>
{% endfor %}
模板的渲染  将后端传递给html文件的数据  在后端处理好 生成一个完整的html文件的过程
注意 模板的渲染是在后端完成的 跟前端没有关系

动静态页面

静态网页

数据是写死的 万年不变(哪怕改变了,也是人为直接修改)

动态网页

数据是实时获取的

python三大主流web框架

django:

大而全,自带组件和功能非常多 类似航空母舰

不足:写小项目的时候可能会比较笨重(大材小用)

flask:

短小精悍 自带组件和功能特别少 类似于游骑兵

基本全依赖于第三方组件

不足之处:受限于第三方模块的影响比较大

如果将flask所以第三方模块加起来 能够直接盖过django

tornado

异步非阻塞,这个框架基本可以用来开发游戏服务器

a:socket部分
b:路由匹配
c:模板语法

django:
a用的别人的wsgiref(django默认的)
b自己写的
c自己写的
flask:
a用的别人的werkzeug
b自己写的
c用的别人的jinja2
Tornado:
a,b,c都是自己写的
        

django介绍

注意事项
        1.计算机名称不能有中文
        2.python解释器不要使用3.7版本  推荐使用版本3.4~3.6
        3.一个pycharm窗口 只能跑一个项目

django版本问题
        django版本以1.11.11为主(1.11.9~1.11.13)

如何检验django是否安装成功
        命令行敲 django-admin

命令行创建项目
        1.创建django项目
                django-admin startproject 项目名(例如mysite)
        2.启动django项目
                切换到项目文件夹下
                python3 manage.py runserver 
                python3 manage.py runserver 127.0.0.1:8080
        3.创建应用(django支持多app开发)
                python3 manage.py startapp app01
            

注意
    1.不会自动帮你创建templates文件夹
    2.配置文件中不会自动帮你书写templates文件路径

    
app的概念
            django是一个以开发app为主要功能的web框架
            app就是application应用的意思
            
            一个django项目就是一所大学(空的架子 本身没有任何功能)
            而app就类似于大学里面的各个学院
            
            一个空的django本身没有任何作用 仅仅是为app提高前期的环境配置
            
            你可以根据功能的不同 开发多个app
            一个app对应一个具体的功能模块
                用户相关的功能  用户相关的app
                订单相关的功能  订单相关的app
                商品相关的功能  商品相关的app
                每一个app都有自己独立的功能
******************************注意***************************
        创建好的app需要在django配置文件中注册方可生效
        INSTALLED_APPS = [
            'django.contrib.admin',
            'django.contrib.auth',
            'django.contrib.contenttypes',
            'django.contrib.sessions',
            'django.contrib.messages',
            'django.contrib.staticfiles',
            # 'app01'  # 简便写法
            'app01.apps.App01Config'  # 最完整的写法
        ]
        

pycharm创建项目

  1. 创建应用的时候可以使用简便方式

    Tools >>> run manage.py task

  2. 一定要确保同一个端口 同一时间只能启动一个django项目

  3. 配置文件中针对templates文件夹的路径如果是空的需要你手动配置

django文件功能

django项目名
                项目同名的文件夹
                    settings.py  暴露给用户可以配置的配置文件
                    urls.py      路由与视图函数对应关系
                manage.py        django的入口文件
                应用名文件夹
                    migrations文件夹     所有数据库相关的操作记录
                    admin.py             django admin后台管理
                    apps.py              注册app使用
                    models.py            放所有数据库相关的模型类
                    tests.py             测试文件
                    views.py             处理业务逻辑的视图函数
django基本配置及注意事项
    
    django小白必会三板斧
        HttpResponse  返回字符串
        
        
        render        返回html文件
                        可以给html页面传值
                def login(request):
                    user_dic = {'username':'jason','password':'123'}
                    return render(request,'login.html',{'xxx':user_dic})
        
        
        redirect       重定向
                    
                    1.直接写你本网站的路径后缀
                    2.也可以全路径
        
                def home(request):
                    # return redirect('/login')  # 重定向
                    return redirect('https://www.baidu.com')  # 重定向
        
    注意
        django默认是自动重启的
            重启机制
                内有检测机制 实时检测所有文件的变化
                有时候会产生 你代码还没写完 就自动重启报错的情况 不用管
            每次写完代码之后 自己手动重启

以上是关于仿Django框架-基于wsgiref模块和jinja2模块写一个简单的框架 主流框架简介 动静态网页 Python虚拟环境的主要内容,如果未能解决你的问题,请参考以下文章

2基于wsgiref模块DIY一个web框架

Python Django前奏手撸web框架 基于wsgiref的web框架

Django简介

Django初窥

web框架底层原理;django介绍

python面试题——框架和其他(132题)