web框架入门

1. HTTP协议

超文本传输协议:
1.四大特性
	1.基于TCP/IP之上作用于应用层
	2.基于请求响应
	3.无状态   cookies  session  token
	4.无连接
		长连接  websocket(HTTP协议的大补丁)
		
2.数据格式
	请求格式
		请求首行(请求方式,协议版本...)
		请求头(一大堆k:v键值对)
		

		请求体(真正的数据 发post请求时才有 如果是get请求不会有)
		响应首行
		响应头
		

		响应体
		
3.响应状态码
	用特定的数字表示一些意思
	1xx:服务端已经成功接收到了你的数据 正在处理 你可以继续提交其他数据
	2xx:服务端成功响应(200请求成功)
	3xx:重定向
	4xx:请求错误(404:请求资源不存在  403:拒绝访问)
	5xx:服务器内部错误(500)

2. 请求方式

get请求:朝别人要数据
post请求:向别人提交数据(eg:用户登录)

url:统一资源定位器

3. 纯手写web框架

import socket

server = socket.socket()
server.bind(('127.0.0.1', 8001))
server.listen(5)

'''
请求首行
b'GET / HTTP/1.1

请求头
Host: 127.0.0.1:8888

Connection: keep-alive

Cache-Control: max-age=0

Upgrade-Insecure-Requests: 1

User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36

Sec-Fetch-Mode: navigate

Sec-Fetch-User: ?1

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3

Sec-Fetch-Site: none

Accept-Encoding: gzip, deflate, br

Accept-Language: zh-CN,zh;q=0.9



请求体
'

'''

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

')
    data = data.decode('utf8')
    current_path = data.split('
')[0].split(' ')[1]
    # print(current_path)
    if current_path == '/index':
        with open(r'F:实习python1018web框架推导	emplatesindex.html', 'rb') as f:
            conn.send(f.read())
    elif current_path == '/login':
        conn.send(b'login')
    else:
        conn.send(b'404 error')
    conn.close()

4. 基于wegiref模块

# urls.py  路由与视图函数对象关系
# views.py  放的是视图函数(处理业务逻辑的)
# templates  模板文件夹(一堆html文件)

# urls.py
from views import *

urls = [
    ('/index',index),
    ('/login',login),
    ('/xxx',xxx),
    ('/get_time',get_time),
    ('/get_user',get_user),
    ('/get_db',get_db)
]


# views.py
import datetime
from jinja2 import Template

def index(env):
    return 'index'

def login(env):
    return 'login'

def error(env):
    return '404 error'

def xxx(env):
    return 'xxx'

def get_time(env):
    time = datetime.datetime.now().strftime('%Y-%m-%d %X')
    with open(r'F:实习python1018web框架推导	emplatesget_time.html','r',encoding='utf8')as f:
        data = f.read()
    data = data.replace('$$time$$',time)
    return data

def get_user(env):
    d = {'name':'aa','pwd':'123','hobby':['read','running','music']}
    with open(r'F:实习python1018web框架推导	emplatesget_user.html','r',encoding='utf8') as f:
        data = f.read()
    temp = Template(data)
    res = temp.render(user=d)   # 将字典d传递给前端页面 页面上通过变量名user就能够获取到该字典
    return res


# 基于wsgiref.py
import pymysql
def get_db(env):
    conn = pymysql.connect(
        host = '127.0.0.1',
        user = 'root',
        password = 'root',
        database = 'db926',
        port = 3306,
        charset = 'utf8',
        autocommit = True,
    )
    cursor = conn.cursor(pymysql.cursors.DictCursor)
    sql = 'select * from bank'
    cursor.execute(sql)
    res = cursor.fetchall()
    print(res)
    with open(r'F:实习python1018web框架推导	emplatesget_db.html','r',encoding='utf8') as f:
        data = f.read()
    temp = Template(data)
    res1 = temp.render(info_list = res)
    return res1

from wsgiref.simple_server import make_server
from urls import urls
from views import error


def run(env, response):
    """
    :param env: 请求相关的所有数据
    :param response: 响应相关的所有数据
    :return
    """
    response('200 OK', [])
    current_path = env.get('PATH_INFO')
    func = None
    # for循环 匹配后缀
    for url in urls:
        if current_path == url[0]:
            func = url[1]   # 一旦匹配成功 就将匹配到的函数名赋值给func变量
            break   # 主动结束匹配
    # 判断func是否有值
    if func:
        res = func(env)
    else:
        res = error(env)
    return [res.encode('utf8')]


if __name__ == '__main__':
    server = make_server('127.0.0.1', 8000, run)
    # 实时监听该地址  只要有客户端来连接 统一交给run函数去处理
    server.serve_forever()

5. 动静态网页

静态网页:数据是写死的 万年不变

动态网页
数据是实时获取的
eg:
1.后端获取当前时间展示到前端
2.后端获取数据库中的数据展示到前端

后端获取的数据 传递给html页面 >>>: 模板的渲染

jinja2

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

<p>{{ user }}</p>
		<p>{{ user.name }}</p>
		<p>{{ user['pwd'] }}</p>
		<p>{{ user.get('hobby') }}</p>
		
		
		{% for user_dict in user_list %}
			<tr>
				<td>{{ user_dict.id }}</td>
				<td>{{ user_dict.name }}</td>
				<td>{{ user_dict.pwd }}</td>
			</tr>
		{% endfor %}

6. python三大主流web框架

Django:
	大而全 自带的功能特别特别多 类似于航空母舰
	有时候过于笨重
	
Flask
	小而精 自带的功能特别特别少 类似于游骑兵
	第三方的模块特别特别多,如果将flask第三方模块全部加起来 完全可以超过django
	比较依赖于第三方模块
	
Tornado
	异步非阻塞
	牛逼到可以开发游戏服务器
		
		
A:socket部分
B:路由与视图函数对应关系
C:模板语法
	
Django:
	A用的别人的  wsgiref
	B自己写的
	C自己写的
Flask
	A用的别人的  werkzeug(基于wsgiref)
	B自己写的
	C用的别人的  jinja2
Tornado
	三者全是自己写的

注意事项
	1.计算机的名称不能有中文
	2.一个pycharm窗口就是一个项目
	3.项目名里面尽量不要用中文
    
django安装
	pip3 install django==1.11.11
    
验证django是否安装成功
	命令行直接敲django-admin
    
一个django项目就类似于是一所大学,而app就类似于大学里面的学院
django其实就是用来一个个应用的
一个app就相当于一块独立的功能
	用户功能
	管理功能
django支持任意多个app

如何使用:
1.命令行使用
    创建django项目
    	django-admin startproject mysite
    启动django项目
        python manage.py runserver
    创建应用app
        python manage.py startapp app01
            
注意:
	1.新创建的app需要去settings配置文件中手动在TEMPLATES写配置: os.path.join(BASE_DIR, 'templates')
	2.pycharm只会帮你注册第一个你在创建项目的时候写的应用
    3.使用命令行创建django项目 不会自动帮你创建templates文件夹只能自己创建
  

2.pycharm使用
	在启动django项目的时候 你一定要确保一个端口只有一个django项目
   
项目名
    跟项目名同名的文件夹
        settings.py  暴露给用户的配置文件
        urls.py  路由与视图函数对应关系
    应用名
        migrations文件夹  存放数据库迁移记录的
        admin.py  django后台管理
        apps.py  注册相关
        models.py  模型类 
        tests.py  测试文件
        views.py  存放视图函数
    templates文件夹  存放html文件
    manage.py  django入口文件
原文地址:https://www.cnblogs.com/yushan1/p/11707878.html