手書きLiteのWebフレームワーク

Webフレームワーク

Webアプリケーションフレームワーク(Webアプリケーションフレームワーク)は、動的なWebサイト、Webアプリケーションおよびネットワークサービスの開発を支援する開発フレームワークです。Webアプリケーションフレームワークは、コードの再利用性を向上させることができ、例えば、多くのフレームワークは、データベース等のアクセス・インタフェース、標準モデル、およびセッション管理を提供し、ページの共通の開発活動の負荷を軽減するのに役立ちます。

PythonのWebフレームワークの比較

一般的なPythonのWebフレームワークの簡単な以下の3種類:

ジャンゴ

PythonのフレームワークDjangoは最も広くWebアプリケーションを作成するための展開の一つとなっています。Djangoは部品のほとんどが必要になることがありますが付属しています、したがって、それは代わりに、小さなアプリケーションの大規模なアプリケーションを構築する傾向があります。
wsgirefモジュール、ルーティングおよび表示機能を使用してDjangoのソケットは、テンプレートには、彼の文章をレンダリングされます。

フラスコ

PythonのWebフレームワークの議論のほとんどは、フラスコから冒頭で言及されています。フラスコは、広く使用され、Dapperの、組み込みの機能モジュールは、それらのほとんどは、サードパーティのモジュールに依存している、非常に稀であり、非常に安定して成熟し、理解しやすいフレームワークです。
wsgirefモジュールを使用してソケットのフラスコ、ルーティングとその機能を表示は、サードパーティのモジュールjinjia2を使用して、テンプレートのレンダリングを書かれています。

竜巻

トルネードは別の実施形態では、非同期の自然、強力な性能を持つ小型のフレームに特異的です。トルネードは、いかなるコンテンツWebSocketをまたはロングポーリングに関連すること、同時に生きてそれを維持するためにネットワーク接続およびサービスの大規模な数を作成し、オープンするための理想的な、非同期のWebアプリケーションやデザインを構築するために設計されました。
ソケット、ルーティングおよびビュー機能、テンプレートのレンダリングは、自分のしています。

Webフレームワークの本質

Webアプリケーションは、基本的にソケットサーバであり、ユーザのブラウザがクライアントソケットです。そのように、我々は、Webフレームワークの簡易版を実装するためにHTTPプロトコルに従うことができます。

import socket
server = socket.socket()  # 不传参数默认就是TCP协议
server.bind(('127.0.0.1',8080)) # 绑定IP和端口
server.listen(5)

while True:
    conn, addr = server.accept()  # 阻塞 等待客户端链接
    data = conn.recv(1024)
    # 因为要遵循HTTP协议,所以回复的消息也要加状态行
    conn.send(b'HTTP/1.1 200 OK\r\n\r\n')
    # 手动处理http数据获取用户访问的路径,url是我们从浏览器发过来的消息中分离出的访问路径
    current_path = data.decode('utf-8').split('\r\n')[0].split(' ')[1]
    if current_path == '/index':
        # 路由匹配上之后返回index
        # conn.send(b'<h1>index</h1>')
        with open('index.html','rb') as f:
            # TCP对于发送间隔时间较短和较少的内容会一次发送过去
            conn.send(f.read())
    else:
        # 当匹配不上的时候统一返回404
        conn.send(b'404 not found!')
    conn.close()

このページには表示されますが、静的ああしていることができます。ページの内容は、私は、ダイナミックウェブサイトを望んで、変更されません。

import socket
import time
sk = socket.socket()
sk.bind(("127.0.0.1", 8080))  # 绑定IP和端口
sk.listen(5)  # 监听
# 将返回不同的内容部分封装成函数
def index(url):
    with open("index.html", "r", encoding="utf8") as f:
        s = f.read()
        now = time.strftime('%Y-%m-%d %X')
        res = s.replace("@@time@@", now)  # 在网页中定义好特殊符号,用动态的数据去替换提前定义好的特殊符号
    return res
def home(url):
    with open("home.html", "r", encoding="utf8") as f:
        res = f.read()
    return res
# 定义一个url和实际要执行的函数的对应关系
list1 = [
    ("/index", index),
    ("/home", home),
]
while True:
    # 等待连接
    conn, add = sk.accept()
    data = conn.recv(8096)  # 接收客户端发来的消息
    # 从data中取到路径
    data = str(data, encoding="utf8")  # 把收到的字节类型的数据转换成字符串
    # 按\r\n分割
    data1 = data.split("\r\n")[0]
    url = data1.split(" ")[1]  # url是我们从浏览器发过来的消息中分离出的访问路径
    conn.send(b'HTTP/1.1 200 OK\r\n\r\n')  # 因为要遵循HTTP协议,所以回复的消息也要加状态行
    # 根据不同的路径返回不同内容
    func = None  # 定义一个保存将要执行的函数名的变量
    for i in list1:
        if i[0] == url:
            func = i[1]
            break
    if func:
        response = func(url)
    else:
        response = "404 not found!"
    # 返回具体的响应消息
    conn.send(response.encode('utf-8'))
    conn.close()

WSGI

(WSGIと略記PythonのWebサーバーゲートウェイインターフェイス)PythonWebサーバーゲートウェイインターフェイスフレームワークとPythonアプリケーションやWebサーバ間のインタフェースであり、それが広く受け入れられている、それは基本的に移植するという目標に達しています。WSGI公式実装、WSGIプロトコルのようなより。限り、これらの契約、WSGIアプリケーション(応用)の遵守は任意のサーバ(サーバ)上で実行することができるようので。

wsgirefモジュール

最も単純なWebアプリケーションでは、ユーザーは、要求を受信したHTMLファイルとリターンから読み込み、最初のHTMLファイルは、既存のHTTPサーバソフトウェアで、良いで保存されています。あなたが動的にHTMLを生成したい場合は、自分自身を達成するためにこれらのステップを配置する必要があります。しかし、HTTPリクエストを受け付け、解析HTTPリクエスト、達成するために、あなた自身のことで、クーリーが住んで送信されたHTTPレスポンスは、時間と労力の無駄です。私たちは、TCP接続、HTTPリクエストと、元の応答形式なので、そのようなプロトコル・サーバ・ソフトウェアを実装するための統一されたインタフェースの必要性へのアクセスをしたくないので、私たちは、Pythonを使用してWebサービスを書くことに集中しましょう。Webサーバーゲートウェイインターフェイス:このインタフェースはWSGIです。wsgirefのPythonモジュールはWSGIプロトコルサービスモジュールに基づいて開発されています。

我々は独自のWebフレームワーク書かれたソケット・サーバーの一部を置き換えるためにwsgirefモジュールを使用します。

from wsgiref.simple_server import make_server
import time

def index(env):
    with open("index.html", "r", encoding="utf8") as f:
        s = f.read()
        now = time.strftime('%Y-%m-%d %X')
        res = s.replace("@@time@@", now)  # 在网页中定义好特殊符号,用动态的数据去替换提前定义好的特殊符号
    return res
def home(env):
    with open("home.html", "r", encoding="utf8") as f:
        res = f.read()
    return res

def error(env):
    return '404 error'

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

def run(env,response):
    '''
    :param env:请求相关的信息
    :param response:响应相关的信息
    :return:
    '''
    response('200 OK',[('Content-Type', 'text/html;charset=utf8'), ]) # 设置HTTP响应的状态码和头信息
    # env是一个大字典 里面装了一堆处理好了的键值对数据
    url = env.get('PATH_INFO') # 取到用户输入的url
    func = None
    for url_map in urls:
        if url == url_map[0]:
            func = url_map[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',8080,run)
    server.serve_forever()

Jinja2の

上記のコードは、私は、データベースからデータを照会することができ、簡単なダイナミックを実装し、その後、私はHTMLで対応するコンテンツを交換するために行って、その後、ブラウザに送信されたレンダリングを終えました。このプロセスは、HTMLテンプレートのレンダリングデータに相当します。これは、いくつかの特殊記号を使用するようにHTMLコンテンツを表示するためにデータを交換するために本質的です。実際には、既製のテンプレートのレンダリングツールがあります:jinja2

Jinja2のフラスコは、筆者らが開発したテンプレートシステムで、もともとのテンプレートエンジン模造Djangoテンプレートだった、テンプレートがあるためなど、その、柔軟、迅速かつ安全なのは、広く使用されている、フラスコのためのサポートを提供しています。Jinja2の的環境モジュールストア構成とグローバルオブジェクトに使用されるこのクラスのインスタンス、クラスと呼ばれ、そして、テンプレート・システムまたは他の場所からファイルを読み込みます。

それは次のような利点を持っているので、Jinja2の理由は、広く使用されています。

    1. テンプレートに関しては、制御構造、発現および継承を提供する、より柔軟なJinja2の。
    2. 唯一の制御構造まこに関して、Jinja2のテンプレートにビジネスロジックの多くを書くことは許されません。
    3. Djangoテンプレートに関しては、優れたパフォーマンスをJinja2の。
    4. 読みやす偉大Jinja2のテンプレート。

インストール

Jinja2のは、サードパーティのモジュールに属しているので、それを最初にインストールする必要があります

pip3 install jinja2

htmlファイルをレンダリングJinja2の使用します。

index.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">
            <table class="table table-hover table-striped table-bordered">
                <thead>
                    <tr>
                        <th>id</th>
                        <th>name</th>
                        <th>password</th>
                    </tr>
                </thead>
                <tbody>
                    {% for user in user_dict %}  <!--[{},{},{},{}]-->
                        <tr>
                            <td>{{ user.id }}</td>
                            <td>{{ user.name }}</td>
                            <td>{{ user.password }}</td>
                        </tr>
                    {% endfor %}
                </tbody>
            </table>
        </div>
    </div>
</div>
</body>

PYコード

from wsgiref.simple_server import make_server
from jinja2 import Template
import pymysql

def index(env):
    # 连接数据库 获取数据 渲染到前端页面
    conn = pymysql.connect(
        host = '127.0.0.1',
        port = 3306,
        user = 'root',
        password = 'mysql',
        database = 'jinja',
        charset = 'utf8',
        autocommit = True
    )
    cursor = conn.cursor(pymysql.cursors.DictCursor)
    cursor.execute('select * from userifo')
    user_dict= cursor.fetchall()  # [{},{},{},{}]
    with open(r'templates/index.html','r',encoding='utf-8') as f:
        data = f.read()
    tmp = Template(data)
    return tmp.render(user_dict=user_dict)

def error(env):
    return '404 error'
    
urls = [
    ('/index',index),
]

def run(env,response):
    '''
    :param env:请求相关的信息
    :param response:响应相关的信息
    :return:
    '''
    response('200 OK',[('Content-Type', 'text/html;charset=utf8'), ]) # 设置HTTP响应的状态码和头信息
    # env是一个大字典 里面装了一堆处理好了的键值对数据
    url = env.get('PATH_INFO') # 取到用户输入的url
    func = None
    for url_map in urls:
        if url == url_map[0]:
            func = url_map[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',8080,run)
    server.serve_forever()

おすすめ

転載: blog.csdn.net/linwow/article/details/90921053