Django框架简介
web框架
前端			后端			数据库
客户端发生 >>> 服务端接收 >>> 处理 >>> 返回
'''
web框架:将前端、数据库整合到一起的基于互联网传输的python代码
	web框架也可以简单的理解为是软件开发架构里面的'服务端
'''
# 遵循HTTP协议
	四大特性、数据格式、响应状态码
    
# web框架的本质
所有的Web应用本质上就是一个socket服务端,而且用户的浏览器就是一个socket客户端

基于SOCKET写一个web应用
# 基于不同的后缀响应不同的内容
'''如何获取用户输入的url后缀>>>:HTTP请求数据
    /favicon.ico直接忽略 不影响判断
  利用字符串切割和索引取值获取相应数据'''
import socket
server = socket.socket()
server.bind(('127.0.0.1', 8082)) # IP协议
server.listen(5) # 半链接池
while True:
    sock, addr = server.accept()
    data = sock.recv(1024)
    # 将请求相关数据先转成字符串
    data_str = data.decode('utf8')  # 'GET /login HTTP/1.1\r\nHost: 127.0.0.1:8081\r\n......'
    
    sock.send(b'HTTP1.1 200 OK\r\n\r\n')
    # 然后去字符串中截取出我们需要的内容(按照空格切割字符串 获取第二个元素即可)
    current_path = data_str.split(' ')[1]
    # 根据后缀的不同返回不同的内容
    if current_path == '/login':
        sock.send(b'hello login!!!')
    elif current_path == '/register':
        sock.send(b'hello register')
    else:
        sock.send(b'404 error')
        
"""
上述框架缺陷:
	1.服务端起始代码过于重复 (服务端代码所有人都要重复写)
	2.针对HTTP请求数据没有完善的处理方式
	3.并发量问题
""" 
基于Wsgiref模块
'''
做到后缀的不同返回不同的内容
拿到用户输入的url后缀 做判断
'''
# 1.利用模块搭建服务端
# 2.利用模块处理好的HTTP字典数据编写业务
	查找用户url后缀对象的键值对数据
from wsgiref import simple_server
def run(request, response):
    """
    :param request: 请求相关的数据
    :param response: 响应相关的数据
    :return: 返回给客户端的展示数据
    """
    # print(request)  # 字典类型的数据(模块自动处理HTTP请求数据 便于后续数据获取)
    response('200 OK', [])  # 固定编写 无需掌握
    current_path = request.get("PATH_INFO")
    if current_path == '/login':
        return [b'hello login html']
    elif current_path == '/register':
        return [b'hello register html']
    return [b'404 error']
if __name__ == '__main__':
    server = simple_server.make_server('127.0.0.1', 8080, run)
    '''一致监听本机8080端口 一旦有请求访问 自动触发run方法的执行'''
    server.serve_forever()


优化措施
封装处理
# 出现问题
1.如果网站很多 是不是就是以为的添加elif
2.每个分支下的功能根据业务逻辑的不同可能会比较复杂
# 处理
将匹配和功能封装成 元组和函数
根据功能的不同拆分成不同的py文件
#所有的代码全部放在一个py文件过于冗余 不便于后期管理维护
urls.py						路由与视图函数对应关系
views.py					视图函数(后端业务逻辑)
templates文件夹			   专门用来存储html文件
static文件夹				存储项目所需的'静态文件'
路由:
    路由就是url的后缀
视图函数:
    函数处理的结果,一般都要经过浏览器,所以叫视图函数
    
'''按照功能的不同拆分之后 后续添加功能只需要在urls.py书写对应关系然后取views.py书写业务逻辑即可'''
html所学的css、js、第三方框架代码都是写完之后很少做改动的文件 所以可以统一存放在某个文件夹下
wsgiref.py 启动文件
from wsgiref.simple_server import make_server
# 导入对应关系文件
from urls import urls
# 导入业务逻辑文件
from views import *
def run(env,response):
    """
    :param env: 请求相关的所有数据
    :param response: 响应相关的所有数据
    :return: 返回给浏览器的数据
    """
    # print(env) #大字典 wsgiref模块帮你处理好http格式的数据 让你更好的操作
    response('200 OK',[])  # 响应首行 响应头
    # 从env中取 拿到当前用户输入的后缀
    current_path = env.get('PATH_INFO')
    # 定义一个变量 存储匹配到的函数名
    func = None
    for url in urls:  # url (),()
        # 判断用户输入后缀是否等于列表内的某个元组的第一个元素 访问后面的功能
        if current_path == url[0]:
            # 将url对应的函数名赋值给func
            func = url[1]
            break  # 匹配到一个之后 应该立刻结束当前for循环
    # 判断func是否有值
    if func:
        # 有值情况执行func()
        res = func(env)  # 将env传给函数
    else:
        res = error(env)  # 将env传给函数
    # 统一编码
    return [res.encode('utf-8')]
if __name__ == '__main__':
    # 接收mack_server 的返回值
    server = make_server('127.0.0.1',8080,run)
    """
    会实时监听127.0.0.1:8080地址 只要有客户端来了
    都会交给run函数处理(加括号触发run函数的运行)
    """
    server.serve_forever()  # 启动服务端
urls.py 对应关系
# 导入业务逻辑文件
from views import *
# url与函数的对应关系
urls = [
    ('/index',index),
    ('/login',login),
    ('/xxx',xxx)
]
views.py 业务逻辑 (函数)
def index(env):
    return 'index'
def login(env):
    return 'login'
def error(env):
    return '404 error'
def xxx(env):
    # 打开templates文件夹内的html文件
    with open(r'templates/myhtml.html', 'r',encoding='utf-8') as f:
        return f.read()
动静态网页
# 静态网页
	页面上的数据是直接写死的 万年不变
  	eg:上述项目中编写的 error.html func.html
# 动态网页
	页面上的数据是通过代码动态获取的 实时可变
  	eg:
      1.页面上展示当前时间(后端获取传递给前端界面)
      2.页面上展示数据库数据(后端链接数据库查询数据再传递给页面)
展示当前时间案例
def get_time(request):
    # 1.获取当前时间
    import time
    c_time = time.strftime('%Y-%m-%d %X')
    # 2.读取html文件
    with open(r'templates/get_time.html','r',encoding='utf8') as f:
        data = f.read()
    # 3.思考:如何给字符串添加一些额外的字符串数据>>>:字符串替换
    new_data = data.replace('asdaksdjal',c_time)
    return new_data
jinja2模块
# 第三方模块
	pip3 install jinja2
# 功能介绍
	在编写前后端不分离项目的时候 可以使用该模块提供的模板语法简单快速的在html页面是使用类似于后端的代码语法操作数据
    
# 模板语法
'将一个字典传递给html文件 并且可以在文件上方便快捷的操作字典数据'
  temp_obj.render({'user':user_dict,'new_list':new_list})
	<p>{{ user }}</p>
  <p>{{ user.name }}</p>
  <p>{{ user['pwd'] }}</p>
  <p>{{ user.get('hobby') }}</p>
  
  {% for i in new_list %}
        <span>元素:{{ i }}</span>
  {% endfor %}
后端获取数据库中数据展示到前端页面
后端代码:
import pymysql
def get_user(env):
    # 去数据库中获取数据 传递给html页面 借助于模板语法 发送给浏览器。
    # 创建连接
    conn = pymysql.connect(  # 赋值给conn连接对象
        host = '127.0.0.1',  # 本地回环地址ip
        port = 3306,  # 端口
        user = 'root',  # 用户名
        password = '123',  # 密码
        db='day01',  # 连接数据库名称
        charset = 'utf8',  # 编码
        autocommit = True  # 自动提交
    )
    # 生成一个游标对象(相当于cmd打开MySQL中的 mysql>)
    cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)  # 让数据自动生成字典
    # 定义sql语句
    sql = 'select * from userinfo'
    # 执行sql语句
    affect_rows = cursor.execute(sql)
    # [{},{},{}] 拿到的列表套字典
    data_list = cursor.fetchall()
    # 将获取到的数据传递给html文件
    with open(r'templates/get_data.html','r',encoding='utf-8') as f:
        data = f.read()
        # 使用jinja2 就可以给html文件传值
    tmp = Template(data)
    # 给get_dict.html传递了一个值 页面上通过变量名user_list就能够拿到data_list
    res = tmp.render(user_list=data_list)
    return res
if __name__ == '__main__':
    get_user(111)
前端代码:
<!--表格展示 列表套字典的数据     模板语法支持for循环-->
<div class="container">
    <div class="row">
        <div class="col-md-8 col-md-offset-2">
            <h1 class="text-center">用户数据</h1>
            <table class="table table-hover table-striped">
                <thead>
                    <tr>
                        <th>ID</th>
                        <th>username</th>
                        <th>password</th>
                        <th>hobby</th>
                    </tr>
                </thead>
                <tbody>
<!--[{},{},{},{}]  下面有一个列表套字典的用户数据 每拿一个字典 渲染一个tr-->
				<!--模块语法操作-->
                    {% for user_dict in user_list %}
                    <tr>  
                        <td>{{ user_dict.id}}</td>
                        <td>{{ user_dict.name}}</td>
                        <td>{{ user_dict.password}}</td>
                        <td>{{ user_dict.hobby}}</td>
                    {% endfor%}
                    </tr>
                </tbody>
            </table>
        </div>
    </div>
</div>

框架请求流程
urls.py
	后缀与函数名对应关系
  ('/index',register)
  	后缀专业名词称之为'路由'
    函数名专业名词称之为'视图函数'
    urls.py专业名词称之为'路由层'
views.py
	专门编写业务逻辑代码
  	可以是函数 也可以是类
    	函数专业名词称之为'视图函数'
    	类专业名词称之为'视图类'
      views.py专业名词称之为'视图层'
templates文件夹
	专门存储html文件
  	html文件专业名词称之为'模板文件'
    templates文件夹专业名词称之为'模板层'
    
'''
wsgiref模块
	1.请求来的时候解析http格式的数据 封装成大字典
	2.响应走的时候给数据打包成符合http格式 再返回给浏览器
'''

python主流web框架
# django
	特点:大而全 自带的功能特别特别特别的多 类似于航空母舰
        
	不足之处:
		有时候过于笨重
# flask
	特点:小而精  自带的功能特别特别特别的少 类似于游骑兵
	第三方的模块特别特别特别的多,如果将flask第三方的模块加起来甚至比django还多 并且也越来越像django
    
	不足之处:
		比较依赖于第三方的开发者,有时候也会受限于第三方模块
		
# tornado
	特点:异步非阻塞 支持高并发
	速度非常快 快到甚至可以开发游戏服务器
        
	不足之处:
		暂时你不会
        
'''
还有一些占比较小  但是也很厉害的框架
	fastapi、sanic......
'''
django框架简介
# 版本问题
  django3.X:默认支持异步功能
  django2.X:默认不支持异步
  django1.X:默认不支持异步
 '''
	我们学习的时候 可以基于django1.11.X版本 与2.X功能几乎一致
	3.X仅仅是多了一个功能(并且该功能目前还不完善 半成品!!!)
'''   
# 面试关于Django讲解
之前使用的是1.11 有些新项目逐步过渡到2.2 自己私下也研究过3.2

django下载
# 命令行安装
pip3 install django (最新版本)
pip3 install django==1.11.11
    
# pycharm下载django模块
如果之前下载了其他版本不用管 自动替换
'''如果报错 看看是不是timeout 如果是 那么只是网速波动
重新安装即可'''

验证是否下载成功
终端输入django-admin

命令行创建django项目
# 创建项目
django-admin startproject 项目名
django-admin startproject mysite
# 项目目录
'''
mysite文件夹
manage.py
mysite文件夹
__init__.py
settings.py
urls.py
wsgi.py
'''
启动django项目
# 切换到项目目录下
cd 项目名(mysite) 
    python3 manage.py runserver IP:PORT
        
# 可以指定端口 本地回环地址
python3 manage.py runserver 127.0.0.1:8080
python3 manage.py runserver 8080
django创建app应用
# 切换到项目路径创建应用
cd 项目名 	: 
# 命令行创建应用
python3 manage.py startapp 应用名
python3 manage.py startapp app01
 '''命令行无法自动创建模板文件夹 需要自己执行命令创建''
app概念
# django是一款专注于开发app(应用)的web框架
django本身类似于是一个空壳子 真正的功能是由里面的各个应用决定
django框架相当于是一所大学 应用相当于是大学里面的各个学院
	大学其实是个壳子 负责提供环境 
  学院才是一个个真正具备特定功能的集合
# 举例说明
 使用django写一个淘宝
  	淘宝里面有很多功能模块
我们应该先创建一个空的django项目然后根据功能的不同创建不同的应用
django项目
app01(user)   用户模块
app02(order)  订单没款
app03(goods)  商品模块
app04(address) 收货地址
' 应用名应该做到见名知意'
pycharm操作django
1.new project
  	选择django 填写应用即可
    '''pycharm默认会自动帮你创建模板文件夹 并提供创建一个app的功能'''
2.创建更多的app
  	tools
    	run manage.py task 命令自动提示
	输入:startapp app01
3.启动项目
  	直接点击绿色箭头 
    	还可以修改端口号 edit configurations

django主要文件介绍
mysite项目文件名
	mysite同名文件夹
  	# settings.py		项目配置文件
    # urls.py				路由层
    # manage.py
  	django入口文件 很多命令都需要该文件支持
    # db.sqlite3
  	django启动之后才会生成的文件 其实就是django自带的小型数据库
    # templates文件夹                  模板层
    
app01应用文件夹
  	# migrations文件夹			数据迁移记录
    # admin.py		        django自带的后台管理
    # apps.py			    用于app的注册
    # models.py			    模型层 专门用于操作数据库
    # views.py				视图层 主要用来写逻辑的
    #tests.py			     测试文件
