Django 01

手撸web框架

纯手工实现

import socket

server = socket.socket()
server.bind(("127.0.0.1", 9527))
server.listen(5)

while True:
    conn, addr = server.accept()

    data = conn.recv(1024)
    # print(data)
    # 从请求首行可以拿到 路由(url后缀) 比如下面的 /index
    
    """
    b'GET /index HTTP/1.1

    Host: 127.0.0.1:9527

    Connection: keep-alive

    Cache-Control: max-age=0

    Upgrade-Insecure-Requests: 1

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

    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

    Sec-Fetch-Mode: navigate

    Accept-Encoding: gzip, deflate, br

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

    Cookie: csrftoken=k3cTioICYawfIDXkMpRutozcAavo3T3MQbGKT7EJ0xbxGcqs263Xp9PWfDeEnhb2

'
    """

    data_str = data.decode("utf-8")
    # 获取当前url后缀
    current_routing = data_str.split("/r/n")[0].split(" ")[1]

    # 响应首行 + 空行
    conn.send(b"HTTP/1.1 200 OK

")
    if current_routing == "/index":
        with open(r"index.html", "rb") as f:
            # 响应体
            conn.send(f.read())
    else:
        conn.send(b"404 error")

    conn.close()

wsgiref模块实现

  • web server gateway interface
from wsgiref.simple_server import make_server


urls = [("/get_user_info", get_user_info)]

import pymysql
from jinja2 import Template


def get_user_info(env):
    conn = pymysql.connect(
        host="127.0.0.1",
        port=3306,
        user="root",
        passwd="123",
        db="mysite",
        charset="utf8",
        autocommit=True
    )

    cursor = conn.cursor(pymysql.cursors.DictCursor)
    sql = "select * from user"

    cursor.execute(sql)

    user_list = cursor.fetchall()

    with open(r"get_user_info.html", "r", encoding="utf-8") as f:
        data = f.read()
    temp = Template(data)
    res = temp.render(user_list=user_list)
    return res


def error(env):
    return "404 error"


def run(env, response):
    """
    :param env: 请求相关数据, 提请处理成了字典的形式
    :param response: 响应相关数据
    :return: 给前端的真正数据
    """
    response("200 OK", [('', '')])

    current_routing = env.get("PATH_INFO")

    func = None
    for url in urls:
        if current_routing == url[0]:
            func = url[1]
            break

    if func:
        res = func(env)

    else:
        res = error(env)

    return [res.encode("utf-8"), ]


if __name__ == '__main__':
    server = make_server("127.0.0.1", 9527, run)
    server.serve_forever()

  • get_user_info.html 文件
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
    <div class="row">
        <div class="col-md-8 col-md-offset-2">
            <h2 class="text-center">用户数据</h2>
            <table class="table table-striped table-bordered table-hover">
                <thead>
                    <tr>
                        <th>id</th>
                        <th>username</th>
                        <th>password</th>
                    </tr>
                </thead>
                <tbody>
                    {% for user_dict in user_list %}
                        <tr>
                            <td>{{ user_dict.id }}</td>
                            <td>{{ user_dict.username }}</td>
                            <td>{{ user_dict.password }}</td>
                        </tr>
                    {% endfor %}
                </tbody>
            </table>
        </div>
    </div>
</div>
</body>
</html>

动静态网页

动态页面

  • 数据是实时获取的
    • 后端代码动态获取
    • 数据从数据库查询出来

静态页面

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

jinja2模块语法

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

  • 模板语法

    • 让你在html代码中, 也能够用后端python语法来操作后端传过来的数据
  • 模板渲染

  • 将py文件传递给html文件的数据, 在后端处理好, 生成一个完整的html文件的过程.

    • 模板渲染是在后端完成的, 跟前端没有关系

python三大主流框架

django

  • 大而全, 自带组件和功能非常非常多
  • 写小项目的时候, 比较笨重

flask

  • 小而精, 自带组件和功能特别特别少, 基本依赖第三方组件
  • 受限于第三方模块的影响比较大

tornado

  • 异步非阻塞, 效率极高, 甚至可以用来开发游戏服务器

补充

a: socket部分

b: 路由匹配

c: 模板语法

  • django:
    • a用的是别人的wsgiref
    • b自己的
    • c自己的
  • flask
    • a用的是别人的werkzeug
    • b自己写的
    • c用的别人的jinja2
  • tornado
    • a, b, c都是自己写的

命令行创建

创建项目

  • django-admin startproject <projectname>

启动项目

  • 先切换到项目目录
  • python manage.py runserver
  • python manage.py runserver 127.0.0.1:8080

创建应用

  • python manage.py startapp <appname>

注意

  • 不会自动帮你创建 templates 文件夹

  • 配置文件中不会自动帮你添加 templates 文件路径

  • 自己创建的app需要在django配置文件 settings 中注册方可生效

    • INSTALLED_APPS 中添加 app01.apps.App01Config 或者 aap01
  • 同一个端口, 同一时间只能启动一个django项目

pycharm创建

创建项目

  • file--new project--django

启动项目

  • 通过pycharm的terminal命令行启动
  • 点击快捷执行按钮

创建应用

  • 通过pycharm的terminal命令行添加

注意

  • 配置文件中 TEMPLATES 文件夹的路径如果是空的, 需要手动添加
TEMPLATES = [
					{
						'BACKEND': 'django.template.backends.django.DjangoTemplates',
                        # 如果没有DIRS这一行需要手动添加
						'DIRS': [os.path.join(BASE_DIR, 'templates')]
						,
						'APP_DIRS': True,
						'OPTIONS': {
							'context_processors': [
								'django.template.context_processors.debug',
								'django.template.context_processors.request',
								'django.contrib.auth.context_processors.auth',
								'django.contrib.messages.context_processors.messages',
							],
						},
					},
				]

django文件功能

三个基本方法

  • HttpResponse 返回字符串
  • render 返回html文件
  • redirect 重定向
from django.shortcuts import render, HttpResponse, redirect


# Create your views here.

def index(request):
    return HttpResponse("欢迎来到index页面")


def login(request):
    user_dict = {"username": "bigb", "password": "123"}
    return render(request, "login.html", {"user_info": user_dict})


def home(request):
    # return redirect("/login")
    return redirect("https://www.baidu.com")

  • 注意: 在 views.py 中添加可视图函数, 需要在 urls.py 中添加路由和视图函数匹配关系
原文地址:https://www.cnblogs.com/bigb/p/11908541.html