HTTP协议,web框架,wsgiref模块,Django简介,安装 #day50

软件开发架构

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键值对)
  \r\n
        请求体(并不是所有的请求方法都有get没有,post有,主要用来携带敏感性数据)
    响应数据格式
  响应首行(响应状态码...)
        响应头(一大堆K:V键值对)
  \r\n
         响应体(展示给用户的数据)
# 3.响应状态码
用简单的数字来表示一串中文意思(http协议规定)
   1XX:服务端已经接受到你的数据正在处理,你可以继续提交
   2XX:200 OK>>>:请求成功
   3XX:重定向(原本想访问A但是内部跳到B)
   4XX:403当前请求不符合条件 404请求资源不存在
   5XX:服务器内部错误
  ps:除了上述统一的响应状态码之外,公司还可以自定义自己的状态码
# 4.业务状态码(一般规定一个正确的,只规定200是正确的,其他的全部为异常)
eg:
  1、用户名不存在
       2、验证码错误
      1)随机生成
           2)校验验证码
           存入验证码到数据库(MySQL),表结构
          id code phone create_time
                1    123456  110  2021-10-01 10:10:10
                2    123457  110  2021-10-01 11:10:10
                3    123458  110  2021-10-01 12:10:10
                       
                     通过表结构可以对一天当中的验证码输错次数做限制
                       
            redis也可以存
            如果一天当中,不限制发送次数,存到session中
 
       3、密码错误

       4、告诉前端用户名不存在,密码错误或验证码错误
       json.dumps({})
       # 当业务分模块的时候,定义code值,增加数字头,用来识别各个部门
       eg:
           crm11, 财务12, 销售13, 主站14
       def index()
           user_dic = {'code':121001, 'msg':'验证码错误', 'data':[]}
           user_dic = {'code':121002, 'msg':'用户名不存在', 'data':[]}
           user_dic = {'code':121003, 'msg':'密码错误', 'data':[]}

           # 如果都正确
           user_dic = {'code':200, 'msg':'OK', 'data':[]}
           return JSONrESPONSE(user_dic) #一般公司内部已经封装好的

   
# 5.补充
   https:更加安全,需要申请证书 (通过Nginx服务器实现)
   http:不安全
   
url:统一资源定位符(网址 域名:login.taobao.com
路径:/newlogin/login.do get参数:appName=taobao&fromSite=0&_bx-v=2.0.47
   
https://login.taobao.com/newlogin/login.do?appName=taobao&fromSite=0&_bx-v=2.0.47

请求方法

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

简易版本web框架

import socket
server = socket.socket()
server.bind(('127.0.0.1', 8080))
server.listen(5)
while True:
   sock, addr = server.accept()
   data = sock.recv(1024)
   print(data)
   sock.send(b'HTTP/1.1 200 OK\r\n\r\n')
   data = data.decode('utf-8')
   current_path = data.split(' ')[1]
   """
      需求:输入不同的后缀,返回不同的内容
          1、知道用户输入的后缀
          2、做判断
              if path == '/index/'
                  :return 'index'
                  :return index()
  """
   # 判断
   if current_path == '/index/':
       sock.send(b'index')
   elif current_path == '/login/':
       sock.send(b'login')
   else:
       sock.send(b'404')
   sock.close()
server.close()

 

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

问题

  • 服务端代码重复

  • 手动处理http数据格式过于繁琐

基于wsgiref模块撸

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


def run(request,response):
   """
  :param request:请求相关的所有数据
  :param response:响应相关的所有数据
  :return:返回值
  """
   print(request) # 大字典格式,帮我们封装了http请求过来的所有数据
   response('200 OK',[])
   current_path = request.get("PATH_INFO") # /index/
   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.纯手撸web框架
2.wsgiref模块
1.封装了socket代码
  2.处理了http数据格式
3.根据功能的不同拆分成不同的文件夹
urls.py 路由与视图函数对应关系
   views.py  视图函数
   templates  模板文件夹
  # 1.第一步添加路由与视图函数的对应关系
  # 2.去views中书写功能代码
  # 3.如果需要使用到html则去模板文件夹中操作

主流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-09 19:41  Gnomeshghy  阅读(113)  评论(0)    收藏  举报