Django-手のラインとシンプルなWebフレームワーク - 動的なWebページ-wsgirefフレームワークの比較の主流知人-jinja2知人-python -00

自分では、Webフレームワークの簡易版を達成します

3つのPythonのWebフレームワークを見る前に、まず、自分を達成しました。

備考:

このセクションでは、マスターするアイデアの実現に焦点を当て、コードがポイントではありません

コード、考慮されていない多くの詳細は、アイデアの実現に焦点を当て、そこにあります

ハンドラインとWebサーバ

私たちは、一般的に、クライアントとブラウザを使用して、サーバー側のコードを書くために、HTTPプロトコルに基づいてサーバとして

まず見に行かなければならないHTTPプロトコル一緒に、このの知識

import socket
server = socket.socket()  # 基于socket通信(TCP)
server.bind(('127.0.0.1', 8080))
server.listen(5)
while True:
    conn, addr = server.accept()
    data = conn.recv(2048)  # 接收请求
    print(str(data, encoding='utf-8'))
    conn.send(b'HTTP/1.1 200 OK\r\n\r\n')  # 依据HTTP协议,发送响应给客户端(浏览器),这里是响应首行 + 响应头 + 空行
    # response = bytes('<h3>这是响应内容</h3>', encoding='GBK')
    response = '<h3>这是响应内容</h3>'.encode('GBK')  # 我电脑上是GBK编码,所以使用GBK编码将字符串转成二进制
    conn.send(response)  #  继续发送响应体
    conn.close()  # 断开连接(无状态、无连接)

# 浏览器发过来的数据如下
'''
GET / HTTP/1.1
Host: 127.0.0.1:8080
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.90 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Cookie: _qddaz=QD.w3c3g1.j2bfa7.jvp70drt; csrftoken=kJHVGICQOglLxJNiui0o0UyxNtR3cXbJPXqaUFs5FoxeezuskRO7jlQE0JNwYXJs


GET /favicon.ico HTTP/1.1
Host: 127.0.0.1:8080
Connection: keep-alive
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.90 Safari/537.36
Accept: image/webp,image/apng,image/*,*/*;q=0.8
Referer: http://127.0.0.1:8080/
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Cookie: _qddaz=QD.w3c3g1.j2bfa7.jvp70drt; csrftoken=kJHVGICQOglLxJNiui0o0UyxNtR3cXbJPXqaUFs5FoxeezuskRO7jlQE0JNwYXJs
'''

右、その後、実行し、ブラウザにアクセス127.0.0.1:8080レスポンスデータを参照してください

ページ要求でサーバを起動するのに約(私が対処するとき、ページが頻繁に保留状態のネットワークを要求し、非常に明確な理由、通常、このような場合ではない、に直接サーバーを再起動します)

リクエストされたURLに応じて異なる応答処理を実行します。

上記のコードは、それが別の要求に応じて異なり、それをどのように応答するか、要求に基本的な応答を達成しましたか?

私たちは、別のURLを入力して、サーバーが返すものを見ます

分析依頼

浏览器访问 http://127.0.0.1:8080/index
GET /index HTTP/1.1
Host: 127.0.0.1:8080
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/75.0.3770.90 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Cookie: _qddaz=QD.w3c3g1.j2bfa7.jvp70drt; csrftoken=kJHVGICQOglLxJNiui0o0UyxNtR3cXbJPXqaUFs5FoxeezuskRO7jlQE0JNwYXJs
    

浏览器访问 http://127.0.0.1:8080/home   
GET /home HTTP/1.1
Host: 127.0.0.1:8080
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/75.0.3770.90 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Cookie: _qddaz=QD.w3c3g1.j2bfa7.jvp70drt; csrftoken=kJHVGICQOglLxJNiui0o0UyxNtR3cXbJPXqaUFs5FoxeezuskRO7jlQE0JNwYXJs

元の要求の最初の行GET続くが、我々は情報を要求したいということです(/インデックスホーム、/ホームホーム)

この情報は、私たちが(受信するものであるdata = conn.recv(2048) print(str(data, encoding='utf-8')))、それは取り出すことが、その値に応じて異なる方法で処理することができますか?

リクエストを処理して、URLを取得

data = '''GET /home HTTP/1.1
Host: 127.0.0.1:8080
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/75.0.3770.90 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Cookie: _qddaz=QD.w3c3g1.j2bfa7.jvp70drt; csrftoken=kJHVGICQOglLxJNiui0o0UyxNtR3cXbJPXqaUFs5FoxeezuskRO7jlQE0JNwYXJs'''
print(data.split('\n')[0].split(' ')[1])  # ... ---> GET /home HTTP/1.1 --> ['GET', '/home', 'HTTP/1.1']  --> /home
# /home

上記カットルールに基づいて、我々は異なる要求に来る異なる応答へ

import socket
server = socket.socket()
server.bind(('127.0.0.1', 8080))
server.listen(5)
while True:
    conn, addr = server.accept()
    data = conn.recv(2048).decode('utf-8')
    data = data.split('\n')[0].split(' ')[1]
    print(data)
    conn.send(b'HTTP/1.1 200 OK\r\n\r\n')
    if data == '/index':
        response = '<h3>这里是 index...</h3>'.encode('GBK')
    elif data == '/home':
        response = '<h3>这里是 home...</h3>'.encode('GBK')
    else:
        response = '<h3>404 NOT FOUND...\n找不到您要找的资源...</h3>'.encode('GBK')
    conn.send(response)
    conn.close()

# --- 浏览器请求 http://127.0.0.1:8080/index 的打印信息
# /index
# /favicon.ico
# --- 浏览器请求 http://127.0.0.1:8080/home 的打印信息
# /home
# /favicon.ico
# --- 浏览器请求 http://127.0.0.1:8080/de2332f 的打印信息
# /de2332f
# /favicon.ico

成功ページには、異なる情報が表示されます

http://127.0.0.1:8080/index

http://127.0.0.1:8080/home

http://127.0.0.1:8080/de2332f

404ページには、サイトのデザインの一部としてカウントされなければならない、あなたは別の感じを与えることができます

サーバーベースのモジュールを実装Wsgiref

コードの前と処理scoket HTTP杭は通常と同じであり、各プロジェクトは再びそれを書く必要がある場合は関係ありません。ビジネスロジックは、それは多くの問題を意味するのでしょうか?それでは〜モジュールにパッケージ化

しかし、この操作は、すでに私たちを助けるために行われ、より強力なパッケージされた、モジュールはwsgirefです

2つのことを行うためのモジュールとWsgiref

  1. 要求は、自動的にHTTPデータを解析し、辞書にパッケージ場合、操作を介して送信される要求データを容易にします
  2. 任意の応答の前に、自動的に(手動で記述する必要はありません、応答データ・フォーマットHTTPプロトコルを満たすためにデータ形式にパッケージ化conn.send(b'HTTP/1.1 200 OK\r\n\r\n'))、サーバに返さ
from wsgiref.simple_server import make_server  # 导模块


def run(env, response):
    """
    先不管这里的 env 和 response 什么个情况

    env:是请求相关的数据,wsgiref帮我们把请求包装成了一个大字典,方便取值
    response:是响应相关的数据
    """
    response('200 OK', [])
    print(env)
    current_path = env.get('PATH_INFO')
    print(current_path)

    if current_path == '/index':
        return ['hello, there is index...'.encode('utf-8')]
    elif current_path == '/login':
        return ['hello, there is login...'.encode('utf-8')]
    else:
        return ['sorry... that pages you want is not found...'.encode('utf-8')]


if __name__ == '__main__':
    # 实时监测 127.0.0.1:8080 地址,一旦有客户端连接,会自动加括号调用 run 方法
    server = make_server('127.0.0.1', 8080, run)
    server.serve_forever()  # 启动服务器


# /index
# ---> env 的数据(手动删减了一些),可以看到其中有个 PATH_INFO 是我们要的东西(还有浏览器版本啊,USER-AGENT啊,客户端系统环境变量啊之类的信息)
'''{'ALLUSERSPROFILE': 'C:\\ProgramData', ...省略部分... , 'COMSPEC': 'C:\\Windows\\system32\\cmd.exe', 'PROCESSOR_IDENTIFIER': 'Intel64 Family 6 Model 60 Stepping 3, GenuineIntel', 'PROCESSOR_LEVEL': '6', 'PROCESSOR_REVISION': '3c03', 'PYTHONIOENCODING': 'UTF-8',  'SESSIONNAME': 'Console', 'SYSTEMDRIVE': 'C:', 'SERVER_PORT': '8080', 'REMOTE_HOST': '', 'CONTENT_LENGTH': '', 'SCRIPT_NAME': '', 'SERVER_PROTOCOL': 'HTTP/1.1', 'SERVER_SOFTWARE': 'WSGIServer/0.2', 'REQUEST_METHOD': 'GET', 'PATH_INFO': '/index', 'QUERY_STRING': '', 'REMOTE_ADDR': '127.0.0.1', 'CONTENT_TYPE': 'text/plain', 'HTTP_HOST': '127.0.0.1:8080', 'HTTP_CONNECTION': 'keep-alive', 'HTTP_UPGRADE_INSECURE_REQUESTS': '1', 'HTTP_USER_AGENT': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.90 Safari/537.36', 'HTTP_ACCEPT': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3', csrftoken=kJHVGICQOglLxJNiui0o0UyxNtR3cXbJPXqaUFs5FoxeezuskRO7jlQE0JNwYXJs', mode='w' encoding='UTF-8'>, 'wsgi.version': (1, 0), }'''

伏線

スプリット・サーバ・コード

サーバー側のコード、ルーティング設定、表示機能、すべて一緒に、遅い拡張は、この文書は維持するために不便な、非常に長くなりますので、彼が開いて分割することを選択したときに、現在の冗長書き込みに応じて

次のようにサーバーのコードは、3つの部分に分割されています。

  • server.pyは、サーバーのコードを配置しました

  • ルーティングとurls.pyビュー機能の対応関係を置きます

  • views.pyプットビュー機能/タイプ(ビジネスロジック)

views.py

def index(env):
    return 'index'


def login(env):
    return 'login'

urls.py

from views import *

urls = [
    ('/index', index),
    ('/login', login),
]

server.py

from wsgiref.simple_server import make_server  # 导模块
from urls import urls  # 引入 urls.py 里的 urls列表(命名的不是很规范)


def run(env, response):
    response('200 OK', [])
    current_path = env.get('PATH_INFO')

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

    if func:
        res = func(env)
    else:
        res = '404 Not Found.'
    return [res.encode('utf-8')]  # 注意这里返回的是一个列表(可迭代对象才行),wsgiref 模块规定的,可能还有其他的用途吧


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

新しい要求アドレスをサポートしています(新しいページを追加/新機能)

上記の分割した後、それ以降は他のURLをサポートしたい、ただ、中にviews.pyで実現される機能に対応関係のurls.pyを追加アクセスにサーバーを再起動します

サポートするために、http://127.0.0.1:8080/new_url例えば、へのアクセスを

urls.py

from views import *

urls = [
    ('/index', index),
    ('/login', login),
    ('/new_url', new_url),
]

views.py

def index(env):
    return 'index'


def login(env):
    return 'login'


def new_url(env):
    # 这里可以写一堆逻辑代码
    return 'new_url'

サーバーを再起動し、ブラウザを開き、ウェブhttp://127.0.0.1:8080/new_url

拡張たくさんの高い、とロジックが明確に、なぜあまりにも少しで書かれたコードのこの作品の枠組みの理由を書き出していない(撤退の給付枠組みを間違えにくくなり、に慣れていない、とないフレームワークへの書き込み)

動的な静的なページ - スプリットテンプレートファイル

非常に多くの目の前に書かれ、その後、どのようにゴージャスなページに戻して、単なるテキスト情報が返されましたが、我々は一般的に要求されたページが華やかなページをレンダリング良いブラウザで返しますか?

まあページはHTML + CSS + JSレンダリングされるので、我々は戻って直接リターンに応じて、身体上のデータとしてHTMLファイルを置くことができます

ステップ関数の作成や復習を

  • そしてurls.py内部機能との対応関係を考慮して経路を追加
  • ビュー機能付き内部views.py、及び内部ロジックのコードを書きます
  • サーバーを再起動し、ブラウザのページビューを開きます

静的なページに戻る - ケース

ここで我々は、Webページに戻るには、それを使用し、NEW_URL書き込みの上に移動します

[新規作成テンプレートの HTMLファイルを置くように設計されたフォルダを、

テンプレート/ new_url.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>New URL</h1>
    <h5>Wellcome!</h5>
</body>
</html>

views.py

def index(env):
    return 'index'


def login(env):
    return 'login'


def new_url(env):
    # 读取并把 new_url 文件返回给客户端(浏览器)
    with open(r'templates/new_url.html', 'rb') as f:
        html_data = f.read()
    return html_data.decode('utf-8')  # 因为 run 函数那里做了 encode, 而二进制数据没有 encode这个方法,所以这里先解码一下,然后那边再编码一下

サーバーを再起動し、ブラウザを使用してアクセス

上記の静的なページは、静的なページは何ですか?動的ページとは何ですか?

  • 静的ページ:純粋なHTMLページ、データが死んで書かれている、すべて同じURL要求を取得したデータが同じです

  • 動的ページ:バックエンドのデータ登録、データが死んで書かれていませんが、のようなダイナミックなステッチ、次のとおりです。

    フロントページを表示するために、現在のリアルタイムのバックエンド「パス」(プラグ)を取得します

    フロントページの表示にデータベースからバックエンドデータ収集「転送」

復帰時間を実現 - 補間アイデア(動的ページ)

時間内にHTMLに挿入するには?

挿入するために、HTML?それはああを達成置き換えているように見えますか?

html_data = f.read()HTMLが読み出されているように見えるが、また、バイナリ、バイナリ文字列になってデコードすることができ、文字列の置換文字列を置換する方法がありますが、私はちょうどページの内容について書き、その後、時間を置き換えますか?

ゾウの良い最初の塩基HO

テンプレート/ get_time.html書き込み表示ページ

彼に交換する時間を与えるためにしばらくの間、プレースホルダを行うために使用put_times_here

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>北京时间:</h1>
    <h1>put_time_here</h1>
</body>
</html>

urls.pyルーティングとビュー機能の対応関係

from views import *

urls = [
    ('/index', index),
    ('/login', login),
    ('/new_url', new_url),
    ('/get_time', get_time),
]

views.pyビュー機能を実現

def index(env):
    return 'index'


def login(env):
    return 'login'


def new_url(env):
    # 读取并把 new_url 文件返回给客户端(浏览器)
    with open(r'templates/new_url.html', 'rb') as f:
        html_data = f.read()
    return html_data


def get_time(env):
    # 读取并把 get_time 文件返回给客户端(浏览器)
    with open(r'templates/get_time.html', 'rb') as f:
        html_data = f.read().decode('utf-8')
    import time
    html_data = html_data.replace('put_time_here', time.strftime("%Y-%m-%d %X"))
    return html_data

サーバーを再起動し、アクセスするためにブラウザを開きます http://127.0.0.1:8080/get_time

キーアイデア:実際には現在のテンプレートの構文で統一された規制の後半文字、読みやすいと統一された治療、交換するためのプレースホルダの同等の、文字列の置換、フロントエンド形式のプロトタイプを

私達はちょうどブラウザのページレンダリングはの効果を持つことができるまで、ブラウザに返さ良い文字列(HTML形式)に対処する必要があります

Jinja2のモジュールは、動的なページを使用します

Jinja2のモジュールは、テンプレート構文のセットを持って、私はそれが簡単にHTMLでコードを記述するのに役立ちます(私は同じコードビハインドを書きたかった)、チップは、着信データの構文操作後縁の一部を使用できるように、

インストールJinja2の

Jinja2のは、Pythonインタプリタは来ていないので、我々は自分自身をインストールする必要があります

Jinja2のフラスコをフレームに依存するので、フレームはまた、フラスコダウンロード・モジュールがインストールJinja2のを運びます

コマンドライン、pip3 install jinja2又はグラフィカル・ユーザー実装(Djangoのインストール方法を参照)

予備的使用

ここではそのようなことテンプレートの構文は、私たちは簡単に変数のような一部のHTMLのものを記述することができます、と文法Jinja2のを話すことはありません、フォローアップがあるでしょうがあることだけを知っています

ケース - 辞書情報を表示

urls.py

from views import *

urls = [
    ('/index', index),
    ('/login', login),
    ('/new_url', new_url),
    ('/get_time', get_time),
    ('/show_dic', show_dic),
]

views.py

def index(env):
    return 'index'


def login(env):
    return 'login'


def new_url(env):
    # 读取并把 new_url 文件返回给客户端(浏览器)
    with open(r'templates/new_url.html', 'rb') as f:
        html_data = f.read()
    return html_data


def get_time(env):
    # 读取并把 get_time 文件返回给客户端(浏览器)
    with open(r'templates/get_time.html', 'rb') as f:
        html_data = f.read().decode('utf-8')
    import time
    html_data = html_data.replace('put_time_here', time.strftime("%Y-%m-%d %X"))
    return html_data


def show_dic(env):
    user = {
        "username": "jason",
        "age": 18,
    }
    with open(r'templates/show_dic.html', 'rb') as f:
        html_data = f.read()

    # 使用 jinja2 的模板语法来将数据渲染到页面上(替换占位符)
    from jinja2 import Template
    tmp = Template(html_data)
    res = tmp.render(dic=user)  # 将字典 user 传递给前端页面,前端页面通过变量名 dic 就能够获取到该字典
    return res

テンプレート/ show_dic.html書き込みページ

辞書ドット構文のサポートを拡張するJinja2の({{ dic.username }}

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>Nice to meet you~ i'm {{ dic.username }} , and i'm {{ dic.age }} years old.</h1>
    <p>username: {{ dic['username']}}</p>
    <p>age: {{ dic.get('age')}}</p>
</body>
</html>

サーバーを再起動し、アクセスするためにブラウザを開きます http://127.0.0.1:8080/show_dic

なぜ動的な?

あなたは辞書の値を変更する場合は、このページを要求し、また、変更されます表示されるデータは、(この辞書は、一般的に上の別の場所に取得していることに注意してください)


模板语法(贴近python语法): 前端也能够使用后端的一些语法操作后端传入的数据
    {{data.password}}  # jinja2 多给字典做了 点语法支持
    ... 其他的语法,写法
    
    for 循环
    {%for user_dict in user_list%}
        <tr>
            <td>{{user_dict.id}}</td>
            <td>{{user_dict.name}}</td>
            <td>{{user_dict.password}}</td>
        </tr>
    {%endfor%}

高度なケース - ページにデータベースのデータをレンダリング

考え

pymsql 从数据库取数据(指定成 列表套字典 的格式(DictCursor))
后台 python 代码处理数据
交由 jinja2 模块语法渲染到 html 页面上

数据条数不定怎么办?
    有多少条记录就显示多少条呗...循环?
    表格格式先写好,然后循环渲染数据到标签上(特定语法表示循环)

データ準備

データベースの作成django_test_dbをし、次のSQLコマンドを実行

/*
 Navicat MySQL Data Transfer

 Source Server         : localhost-E
 Source Server Type    : MySQL
 Source Server Version : 50645
 Source Host           : localhost:3306
 Source Schema         : django_test_db

 Target Server Type    : MySQL
 Target Server Version : 50645
 File Encoding         : 65001

 Date: 15/09/2019 00:41:09
*/

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for user_info
-- ----------------------------
DROP TABLE IF EXISTS `user_info`;
CREATE TABLE `user_info`  (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `password` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;

-- ----------------------------
-- Records of user_info
-- ----------------------------
INSERT INTO `user_info` VALUES (1, 'jason', '123');
INSERT INTO `user_info` VALUES (2, 'tank', '123');
INSERT INTO `user_info` VALUES (3, 'jerry', '123');
INSERT INTO `user_info` VALUES (4, 'egon', '456');

SET FOREIGN_KEY_CHECKS = 1;

ルーティングとビュー機能を持ちます

urls.py

from views import *

urls = [
    ('/index', index),
    ('/login', login),
    ('/new_url', new_url),
    ('/get_time', get_time),
    ('/show_dic', show_dic),
    ('/get_users', get_users),
]

views.py

def index(env):
    return 'index'


def login(env):
    return 'login'


def new_url(env):
    # 读取并把 new_url 文件返回给客户端(浏览器)
    with open(r'templates/new_url.html', 'rb') as f:
        html_data = f.read()
    return html_data


def get_time(env):
    # 读取并把 get_time 文件返回给客户端(浏览器)
    with open(r'templates/get_time.html', 'rb') as f:
        html_data = f.read().decode('utf-8')
    import time
    html_data = html_data.replace('put_time_here', time.strftime("%Y-%m-%d %X"))
    return html_data


def show_dic(env):
    user = {
        "username": "jason",
        "age": 18,
    }
    with open(r'templates/show_dic.html', 'rb') as f:
        html_data = f.read()

    # 使用 jinja2 的模板语法来将数据渲染到页面上(替换占位符)
    from jinja2 import Template
    tmp = Template(html_data)
    res = tmp.render(dic=user)  # 将字典 user 传递给前端页面,前端页面通过变量名 dic 就能够获取到该字典
    return res


# 先写个空函数在这里占位置,去把 pymysql 查数据的写了再过来完善
def get_users(env):
    # 从数据库取到数据
    import op_mysql
    user_list = op_mysql.get_users()

    with open(r'templates/get_users.html', 'r', encoding='utf-8') as f:
        html_data = f.read()

    from jinja2 import Template  # 其实这个引入应该放在页面最上方去的,但为了渐进式演示代码推进过程,就放在这里了
    tmp = Template(html_data)
    res = tmp.render(user_list=user_list)
    return res

op_mysql.py設定が変更されない場合は、一晩だけの自分である必要

import pymysql


def get_cursor():
    server = pymysql.connect(
        # 根据自己电脑上 mysql 的情况配置这一块的内容
        host='127.0.0.1',
        port=3306,
        user='root',
        password='000000',
        charset='utf8',  # 千万注意这里是 utf8 !
        database='django_test_db',
        autocommit=True
    )
    cursor = server.cursor(pymysql.cursors.DictCursor)
    return cursor


def get_users():
    cursor = get_cursor()  # 连接数据库

    sql = "select * from user_info"  # 把用户的所有信息查出来(一般不会把密码放回给前端的,这里只是为了做演示)
    affect_rows = cursor.execute(sql)
    user_list = cursor.fetchall()
    return user_list

テンプレート/ get_users.htmlユーザー情報表示ページ

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!--  引入jquery bootstrap 文件的 CDN  -->
    <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-hover table-bordered table-striped">
                    <thead>
                    <tr>
                        <th>id</th>
                        <th>username</th>
                        <th>password</th>
                    </tr>
                    </thead>
                    <tbody>
                    <!-- jinja2 的模版语法(for循环) -->
                    {%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>

ブラウザにアクセスしhttp://127.0.0.1:8080/get_users、サーバーを再起動して、ページの効果を見るために、ブラウザに切り替え

導出過程と小さな概要

1.纯手撸web框架
    1.手动书写socket代码
    2.手动处理http数据
    
2.基于wsgiref模块帮助我们处理scoket以及http数据(顶掉上面的歩鄹)
    wsgiref模块
        1.请求来的时候 解析http数据帮你打包成一个字典传输给你 便于你操作各项数据
        2.响应走的时候 自动帮你把数据再打包成符合http协议格式的样子 再返回给前端
    
3.封装路由与视图函数对应关系 以及视图函数文件 网站用到的所有的html文件全部放在了templates文件夹下
    1.urls.py 路由与视图函数对应关系
    2.views.py 视图函数 (视图函数不单单指函数 也可以是类)
    3.templates 模板文件夹
    
4.基于jinja2实现模板的渲染
    模板的渲染
        后端生成好数据 通过某种方式传递给前端页面使用(前端页面可以基于模板语法更加快捷简便使用后端传过来的数据)

フローチャート

小拡張

エンコードまたはデコードすることです、彼らはどのような方法を使用することができます知ってはいけません

文字列に対応するバイナリデータは、それをデコードするためにデコードされなければなりません

文字列に対応するバイナリデータ型を符号化するために符号化されなければなりません

データ型変換技術(符号化処理)(データ+エンコーディング)

# 转成 bytes 类型
bytes(data, encoding='utf-8')

# 转成 str 类型
str(data, encoding='utf-8')

三の大ウェブの分析と比較のためのPythonのフレームワーク

ジャンゴ

空母に似て、特に特殊な大型と機能が付属しています

短所:時々あまりにも重い(小さなプロジェクトの多く未満)

フラスコ

Dapperの、特定の少ない独自の機能では、サードパーティのコンポーネント(モジュール)のすべて依存しています

サードパーティコンポーネントの特に多数 - >あなたはすべてのサードパーティ製のコンポーネントを追加する場合は、ジャンゴの影に隠れことができます

短所:比較的サードパーティの開発者(おそらくバグなど)に限定

竜巻

ナチュラル、ノンブロッキングの非同期フレームを、非常に高速で、耐えることができ、高い同時実行

ゲームサーバ開発することができます(ただし、ゲーム開発、またはCおよびC ++使用されるより、より高速な実行効率)

ハンドラインとフレーム内三つの部分の比較

導出ラインと手の前に、フレームは、大きく3つの部分に分けることができるプロセス全体

:ソケットに応答する処理要求を送受信します

B:ルーティングとビュー機能

C:動的ページの描画データへのテンプレートの構文

ジャンゴ

:で他の人 wsgirefモジュールの
Dailu機能ファイルからの眺め:B
C:テンプレート構文のセットが付属しています

フラスコ

:を有するモジュールWERKZEUG(ベースwsgirefパッケージ)の
ルータとの関数ファイルから眺め:B
C:と Jinja2のの

竜巻

、B、Cのすべてが独自の実装を持っています

基本的な使用ジャンゴをダウンロードしてインストール

私の他のブログ記事を参照してください:Django-ダウンロードしてインストール-設定-簡単な使用して3つのトリック- Djangoプロジェクトを作成します。

おすすめ

転載: www.cnblogs.com/suwanbin/p/11520959.html