01

软件开发架构

1.c/s架构
2.b/s架构
# b/s本质也是c/s架构

HTTP协议

"""规定了浏览器与服务端之间数据交互的格式"""
# 1.四大特性
	 1.基于TCP、IP作用于应用层之上的协议
    2.基于请求响应
    3.无状态
    	见你千百遍我都当你如初见
       ps:cookie、session、token...
    4.无(短)连接
    	ps:长连接:websocket
# 2.数据格式
	 请求数据格式
    	请求首行(请求方法...)
       请求头(一大堆K:V键值对)
    	
       请求体(并不是所有的请求方法都有  主要用来携带敏感性数据)
    响应数据格式
    	响应首行(响应状态码...)
       响应头(一大堆K:V键值对)
    	
       响应体(展示给用户的数据)
# 3.响应状态码
	用简单的数字来表示一串中文意思
    1XX:服务端已经接受到你的数据正在处理,你可以继续提交
    2XX:200 OK>>>:请求成功
    3XX:重定向(原本想访问A但是内部跳到B)
    4XX:403当前请求不符合条件 404请求资源不存在
    5XX:服务器内部错误
   ps:除了上述统一的响应状态码之外,公司还可以自定义自己的状态码

请求方法

1.get请求
	朝别人索要数据
2.post请求
	朝别人提交数据
"""
上述两种请求都可以携带额外的参数
get请求
	url?username=jason&hobby=mn
post请求
	数据是放在请求体里面的
"""

纯手撸web框架

import socket

"""
请求首行
b'GET / HTTP/1.1\r\n  
请求头
Host: 127.0.0.1:8080\r\n
Connection: keep-alive\r\n
sec-ch-ua: "Google Chrome";v="89", "Chromium";v="89", ";Not A Brand";v="99"\r\n
sec-ch-ua-mobile: ?0\r\n
Upgrade-Insecure-Requests: 1\r\n
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36\r\n
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9\r\n
Sec-Fetch-Site: none\r\n
Sec-Fetch-Mode: navigate\r\n
Sec-Fetch-User: ?1\r\n
Sec-Fetch-Dest: document\r\n
Accept-Encoding: gzip, deflate, br\r\n
Accept-Language: zh-CN,zh;q=0.9\r\n
\r\n
请求体
'
"""


server = socket.socket()  # 默认就是TCP协议
server.bind(('127.0.0.1',8080))
server.listen(5)


while True:
    conn, addr = server.accept()  # 三次四次挥手
    data = conn.recv(1024)
    res = data.decode('utf8')
    conn.send(b'HTTP/1.1 200 OK\r\n\r\n')
    # 字符串切割获取地址
    path = res.split(' ')[1]
    # 判断地址
    if path == '/index':
        # conn.send(b'index')
        with open(r'fh.html','rb') as f:
            data = f.read()
            conn.send(data)
    elif path == '/login':
        conn.send(b'login')
    conn.close()

问题

  • 服务端代码重复
  • 手动处理http数据格式过于繁琐

基于wsgiref模块撸

# 解决了上述两个问题
from wsgiref.simple_server import make_server


def run(request,response):
    """
    :param request:请求相关的所有数据
    :param response:响应相关的所有数据
    :return:
    """
    response('200 OK',[])
    current_path = request.get("PATH_INFO")
    if current_path == '/index':
        return [b'index']
    elif current_path == '/login':
        return [b'login']
    return [b'404 error']


if __name__ == '__main__':
    server = make_server('127.0.0.1',8080,run)  # 一旦被访问会全部交给run函数处理
    server.serve_forever()

问题

  • 网址很多的情况下如何匹配
  • 网址多匹配如何解决
  • 功能复杂代码块如何解决

封装处理

1.定义一个网址与功能函数的对应关系
	# 地址与功能的对应关系
    urls = [
        ('/index',index_func),
        ('/login',login_func),
        ('/reg',reg_func),
    ]
2.按照功能的不同划分成不同的py文件
	urls.py views.py 服务端.py
3.书写服务端代码
	 func = None
    # for循环判断
    for url_tuple in urls:  # (),()
        if current_path == url_tuple[0]:
            # 将匹配到的函数名赋值给func变量
            func = url_tuple[1]
            break
    # 判断func是否有值
    if func:
        # 执行对应的函数
        res = func(request)
    else:
        res = errors(request)
    return [bytes(res,encoding='utf8')]

动静态网页

静态网页
	数据全部都是写死的
动态网页
	数据来源于后端(代码、数据库)
  
1.访问网址展示当前时间(由后端模块生成并展示到html页面)
	def get_time_func(request):
    from datetime import datetime
    current_time = datetime.now().strftime('%Y-%m-%d %X')
    with open(r'get_time.html','r',encoding='utf8') as f:
        data = f.read()  # 字符串
    data = data.replace('sadadadad',current_time)
    return data
2.后端有一个字典,将该字段传递给html页面,并且在该页面上还可以使用字典取值的各种操作
	jinja2模块
    	pip3 install jinja2
   	ps:该模块是flask框架必备的模块 所以下载flask也会自动下载该模块
    def get_dict_func(request):
        user_dict = {"username":'jason','password':123,'hobby':'study'}
        from jinja2 import Template
        with open(r'templates/get_dict.html','r',encoding='utf8') as f:
            data = f.read()  # 字符串
        temp = Template(data)
        # 将user_dict传递给get_dict.html页面 在该页面上使用变量名user_data调用
        res = temp.render(user_data=user_dict)
        return res
    模板语法(用近似于python的语法在html文件上操作数据) 
        {{user_data}}
        {{user_data['username']}}
        {{user_data.get('password')}}
        {{user_data.hobby}}
        
        {%for user_dict in data_list%}
            <tr>
                <td>{{user_dict.id}}</td>
                <td>{{user_dict.name}}</td>
                <td>{{user_dict.age}}</td>
            </tr>
       {%endfor%}
3.获取MySQL数据库数据展示到页面上
	def get_db_func(request):
    import pymysql
    conn = pymysql.connect(
        host='127.0.0.1',
        port=3306,
        user='root',
        password='123',
        db='db666',
        charset='utf8',
        autocommit=True
    )
    cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
    sql = 'select * from userinfo'
    affect_rows = cursor.execute(sql)
    res1 = cursor.fetchall()  # [{},{},{}]
    with open(r'templates/get_db.html','r',encoding='utf8') as f:
        data = f.read()  # 字符串
    temp = Template(data)
    # 将user_dict传递给get_dict.html页面 在该页面上使用变量名user_data调用
    res = temp.render(data_list=res1)
    return res

总结

1.纯手撸web框架
2.wsgiref模块
		1.封装了socket代码
    	2.处理了http数据格式
3.根据功能的不同拆分成不同的文件夹
	urls.py	路由与视图函数对应关系
    views.py  视图函数
    templates  模板文件夹
   # 1.第一步添加路由与视图函数的对应关系
   # 2.去views中书写功能代码
   # 3.如果需要使用到html则去模板文件夹中操作
4.jinja2模板语法
	{{}}
    {%%}
5.简易版本web框架流程图

主流web框架

1.django框架
	大而全,自带的功能组件非常非常非常的多!类似于航空母舰
 
2.flask框架
	小而精,自身的功能组件非常非常非常的少!类似于游骑兵
    但是第三方模块非常之多,如果把第三方模块全部叠加起来完全可以盖过django
    有时候也会受限于第三方模块
    ps:三行代码就可以启动一个flask后端服务

3.tornado框架	
	异步非阻塞  速度非常的快 快到可以开发游戏服务器
ps:Sanic、FastAPI...
"""注意:小白不要同时学习两个及以上""" 
A:socket部分
B:路由与视图匹配
C:模板语法
  
django
   A:用的是wsgiref模块
   B:自己写的
   C:自己写的
flask
   A:用的是wsgiref模块封装之后werkzeug
   B:自己写的
   C:jinja2模块
tornado	
	A、B、C都是自己写的

django框架

# 注意事项
	 1.计算机名称不能有中文
    2.项目名和py文件名最好也不要使用中文
    3.django版本问题
    	1.X
       2.X
       3.X
 ps:版本选择1.11.11版本
   
# 命令行下载
	pip3 install django==1.11.11
# 测试是否安装完成
	django-admin

命令行模式

1.创建django项目
	django-admin startproject 项目名
2.启动django项目
	cd 项目名
    python3 manage.py runserver ip:port
 	ps:如果报错需要修改py文件源码
    D:\Python38\lib\site-packages\django\contrib\admin\widgets.py
    152行后面的逗号去掉即可!!!
    	'%s=%s' % (k, v) for k, v in params.items()
3.创建app
	python manage.py startapp app名字

app

django是一款专门开发app(应用)的软件

我们创建一个django项目之后类似于创建了一所大学
而app就类似于大学里面的各个学院,每个学院都可以有自己独立的各项功能职责
django相当于是一个空壳子用来给各个学院提供资源!!!
"""我们创建的app一定要去settings文件中注册才能生效"""

pycharm快捷方式

1.new project
	django
    	项目名
       解释器
    	应用名
 # pycharm会自动帮你创建一个app

总结

命令行与pycharm创建不同点
	1.命令行不会自动创建templates模板文件夹
   2.命令行也不会自动在配置文件中配置模板文件夹路径

django目录结构

mysite
	 mysite文件夹	  # 项目同名文件夹
    	settings.py  # django暴露给用户可以配置的配置文件
       urls.py    # 路由与视图函数(可以是函数也可是类)对应关系(路由层)
       wsgi.py	  # 忽略
    app01文件夹	 # 应用(可以有多个)
    	migrations文件夹   # 存储数据库记录相关(类似于操作日志)
       admin.py    # django后台管理
       apps.py     # 注册app
       models.py   # 数据库相关(模型层)
    	tests.py    # 测试文件
       views.py    # 视图函数(视图层)
    db.sqlite3		# django自带的小型数据库
    manage.py		# django入口文件
    templates      # 模板文件(存储html文件)(模板层)

小白必会三板斧

1.HttpResponse
	返回字符串
2.render
	返回html页面,还可以使用模板语法
3.redirect
	重定向

posted @ 2021-08-16 14:32  简爱cx  阅读(77)  评论(0编辑  收藏  举报