dya49:django:wsgrief&模板渲染Jinjia2&django的MTV/MVC框架&建立/啓動一個django項目

目錄

1.自定義web框架wsgiref版css

2.自定義web框架wsgiref版-優化版html

3.模板渲染JinJa2前端

4.MTV和MVC框架python

5.django:下載安裝&建立啓動mysql

自定義web框架wsgiref版

1.wsgiref構建服務端

wsgiref自己就是個web框架,提供了一些固定的功能(請求和響應信息的封裝),web

有了wsgiref咱們就不須要本身寫原生的socket了sql

也不須要我們本身來完成請求信息的提取了shell

總體結構和socketserver相似數據庫

2.登陸函數邏輯

登陸操做 進入頁面爲get請求 提交數據是post請求django

def login(environ):
    # 回覆login.html
    # environ['QUERY_STRING'] --'username=chao'
    method = environ['REQUEST_METHOD']
    if method == 'GET': # 打開login頁面
        with open('login.html', 'rb') as f:
            data = f.read()
        return data
    else:
        print(environ)
        content_length = int(environ.get('CONTENT_LENGTH',0)) # 獲取'username=asdf&password=asdf的長度

        # environ['wsgi.input']是post對象,對象中內置了read方法,參數是長度,讀出來的是字節流,再decode一下,獲得字符串
        data = environ['wsgi.input'].read(content_length).decode('utf-8') # environ['wsgi.input']是post對象

        #post請求提交過來的數據
        print('請求數據爲', data)   #請求數據爲 b'username=asdf&password=asdf

        # 使用parse_qs的緣由:'username=asdf&password=asdf這個字符串把用戶名和密碼徹底切割出來太麻煩
        # parse_qs能夠將這個字符串格式化成咱們須要的字典,這樣的話取值很是方便
        data = parse_qs(data)
        print('格式化以後的數據',data)  #格式化以後的數據 {'username': ['chao'], 'password': ['123']}

        # 經過字典垂手可得獲取post提交過來的用戶名和密碼
        uname = data.get('username')
        pwd = data.get('password')

        # 調用check函數 檢測用戶名密碼是否正確,返回一個是否成功狀態status
        status = check(uname,pwd)
        # 登陸成功 跳轉到html頁面
        if status:
            data = html(environ)
            return data
        # 登陸失敗 給一個錯誤提示
        else:
            return b'gunduzi'

3.application函數邏輯(替代socket)

def application(environ, start_response):
    '''
    :param environ: 是所有加工好的請求信息,加工成了一個字典,經過字典取值的方式就能拿到不少你想要拿到的信息
    :param start_response: 幫你封裝響應信息的(響應行和響應頭),注意下面的參數
    :return:
    '''
    path = environ['PATH_INFO']
    print(environ)
    '''
    urlpatterns = [
        ('/', html),
        ('/login', login),
        ('/vip.html', vip),
        ('/spa.ico', ico),
        ('/test.css', css),
        ('/test.js', js),
        ('/2.jpg', jpg),

    ]
    '''

   for url in urlpatterns: if url[0] == path: data = url[1](environ) break else: return b'404 page not found' # 封裝響應行和響應頭的 start_response('200 OK', [('a','1'),]) # print(environ) # print(environ['PATH_INFO']) #輸入地址127.0.0.1:8000,這個打印的是'/',輸入的是127.0.0.1:8000/index,打印結果是'/index' return [data] httpd = make_server('127.0.0.1', 8001, application) ''' make_server的做用: 將請求信息處理成一個字典 把 [data] 響應到html頁面 ''' print('Serving HTTP on port 8001...') # 開始監聽HTTP請求: httpd.serve_forever()

4.建立數據庫並插入數據

若是咱們要作一個登錄註冊的一個界面,確定要輸入用戶名和密碼,這時候確定要涉及數據庫的操做了

so 咱們在數據庫中建立一些數據

mysql> create database db1;
Query OK, 1 row affected (0.00 sec)

mysql> use db1;
Database changed
mysql> create table userinfo(id int primary key auto_increment,username char(20) not null unique,password char(20) not null);
Query OK, 0 rows affected (0.23 sec)

mysql> insert into userinfo(username,password) values('chao','666'),('sb1','222');
Query OK, 2 rows affected (0.03 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> select * from userinfo;
+----+----------+----------+
| id | username | password |
+----+----------+----------+
|  1 | chao     | 666      |
|  2 | sb1      | 222      |
+----+----------+----------+
2 rows in set (0.00 sec)

5.pymysql鏈接數據庫對數據庫進行操做

數據建立好了,咱們如今想要用python對數據庫進行操做,因此須要pymysql來鏈接一下

#建立表,插入數據
def createtable():
    import pymysql
    conn = pymysql.connect(
        host='127.0.0.1',
        port=3306,
        user='root',
        password='666',
        database='db1',
        charset='utf8'
    )
    cursor = conn.cursor(pymysql.cursors.DictCursor)
    sql = '''
        -- 建立表
        create table userinfo(id int primary key auto_increment,username char(20) not null unique,password char(20) not null);
        -- 插入數據
        insert into userinfo(username,password) values('chao','666'),('sb1','222');
    '''
    cursor.execute(sql)
    conn.commit()
    cursor.close()
    conn.close()

6.auth登陸驗證

如今有數據庫了,咱們就能夠對用戶名和密碼進行驗證了

在auth函數中傳入用戶輸入的用戶名和密碼,經過select查詢結果肯定用戶名和麪是否正確

#對用戶名和密碼進行驗證
def auth(username,password):
    import pymysql
    conn = pymysql.connect(
        host='127.0.0.1',
        port=3306,
        user='root',
        password='123',
        database='db1',
        charset='utf8'
    )
    print('userinfo',username,password)
    cursor = conn.cursor(pymysql.cursors.DictCursor)
    sql = 'select * from userinfo where username=%s and password=%s;'
    res = cursor.execute(sql, [username, password])
    if res:
        return True
    else:
        return False

7.登陸頁面-login.html

在網頁上,咱們要看到一個用戶名和密碼的輸入框,因此須要建立一個前端html文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!--若是form表單裏面的action什麼值也沒給,默認是往當前頁面的url上提交你的數據,因此咱們能夠本身指定數據的提交路徑-->
<!--<form action="http://127.0.0.1:8080/auth/" method="post">-->
<form action="http://127.0.0.1:8080/auth/" method="get">
    用戶名<input type="text" name="username">
    密碼 <input type="password" name="password">
    <input type="submit">
</form>

<script>

</script>
</body>
</html>

8.登錄成功的跳轉界面

登陸成功後,有一個跳轉頁面,因此須要建立一個跳轉頁面的html文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        h1{
            color:red;
        }
    </style>
</head>
<body>
<h1>寶貝兒,恭喜你登錄成功啦</h1>


</body>
</html>

自定義web框架wsgiref版-優化版

優化版和上面的版本有什麼不一樣?

對以前的版本進行優化,將不一樣的函數按照功能分別寫到不一樣的文件和文件夾中

下面是文件的一個結構圖:

關於上圖的解釋

1.static用於存放一些靜態文件

  包括css js icon jpg圖片這種文件

2.template存放前端html文件

3.auth用來存放一些須要驗證的函數

import pymysql

def check(username, pwd):
    conn = pymysql.connect(
        host='152.136.114.188',
        port=3306,
        user='root',
        password='123456',
        database='django',
        charset='utf8'
    )
    cursor = conn.cursor()
    sql = 'select * from userinfo where username=%s and password=%s;'
    res = cursor.execute(sql, [username, pwd])
    if res:
        return True
    else:
        return False

4.manage.py是用來實現執行命令的函數

這樣咱們在pycharm命令行中經過 python manage.py xxx就能夠執行相關命令了

from models import UserInfo
from wsgi import run

import sys
args = sys.argv
print(args)   #['manage.py', 'migrate']
print(args[1])
if args[1] == 'migrate':
   obj = UserInfo()
   obj.create_model()
elif args[1] == 'runserver':
     ip = args[2]
     port = int(args[3])
     print(ip,port)
     # print(type(port))
     run(ip, port)


 # python manage.py runserver 127.0.0.1 8001

5.models.py是和數據庫相關的

主要完成了用python鏈接mysql的相關配置信息以及python對mysql進行一些增刪改查操做用的

class UserInfo:

    def create_model(self):
        import pymysql

        conn = pymysql.connect(
            host='152.136.114.188',
            port=3306,
            user='root',
            password='123456',
            database='django',
            charset='utf8'
        )
        cursor = conn.cursor()

        sql = '''
            create table userinfo(id int primary key auto_increment, username char(10), password char(10));

        '''
        cursor.execute(sql)
        conn.commit()

6.urls.py是用來肯定url路徑的,而且經過訪問相應的路徑,能夠執行和路徑相關的函數(view)

import views
urlpatterns = [

    ('/home', views.home),
    ('/login', views.login),
    ('/vip.html', views.vip),
    ('/favicon.ico', views.ico),
    ('/test.css', views.css),
    ('/test.js', views.js),
    ('/2.jpg', views.jpg),

]

7.views.py是用來實現主要邏輯的,和項目內容邏輯相關的函數都寫在這裏面

def home(environ):

    msg = {'name': 'chao', 'hobby': ['女人', 'ddj', '小電影']}
    # with open('./templates/index.html', 'rb') as f:
    #     data = f.read()
    with open('./templates/index.html', 'r', encoding='utf-8') as f:
        data = f.read()
    
    t = Template(data)
    ret = t.render(msg)

    return ret.encode('utf-8')

8.wsgi.py是web框架的服務器, 它代替了socket

from urls import urlpatterns
from wsgiref.simple_server import make_server

def run(ip, port):
    # print('xxxxxxxx')
    def application(environ, start_response):
        '''
        :param environ: 是所有加工好的請求信息,加工成了一個字典,經過字典取值的方式就能拿到不少你想要拿到的信息
        :param start_response: 幫你封裝響應信息的(響應行和響應頭),注意下面的參數
        :return:
        '''
        path = environ['PATH_INFO']

        for url in urlpatterns:
            if url[0] == path:
                data = url[1](environ)
                break
        else:
            data = b'404 page not found'


        start_response('200 OK', [('a', '1'), ])

        return [data]

    httpd = make_server(ip, port, application)

    # print('Serving HTTP on port 8001...')
    # 開始監聽HTTP請求:
    httpd.serve_forever()

模板渲染JinJa2

若是咱們想實現一個動態頁面

以前使用的方法是:

假設以時間爲例,在前端頁面上顯示時間戳(刷新就會顯示當前時間戳)

怎麼作到這件事呢?

def html(environ):
    # 1.建立一個當前時間時間戳
    current_time = str(time.time())

    # 2.讀出當前的html文件
    with open('./templates/home.html', 'r', encoding='utf-8') as f:
        data = f.read()
    # 3.將文件中的xxoo替換爲時間戳
    data = data.replace('xxoo', current_time).encode('utf-8')
    return data

在home.html中,搞一個字符串xxoo,而後時間戳就可以替換上去了

<body>
    <!-- 在html文件中,寫一個標籤,其中的內容有xxoo -->
    <h1>皇家賭場--xxoo</h1>
    <a href="http://127.0.0.1:8002/vip.html">會員中心</a>
    <img src="2.jpg" alt="">
    <div class="c1" id="d1"></div>
</body>

其實,這種行爲從專業角度老說,叫作模板渲染

這個過程其實就是HTML模板渲染數據

本質上就是HTML內容中利用一些特殊的符號來替換要展現的數據。

我這裏用的特殊符號是我定義的

其實模板渲染有個現成的工具:JinJa2

用JinJa2實現動態界面

from jinja2 import Template


def index():
    with open("index2.html", "r",encoding='utf-8') as f:
        data = f.read()
    template = Template(data)  # 生成模板文件
    ret = template.render({"name": "于謙", "hobby_list": ["燙頭", "泡吧"]})  # 把數據填充到模板裏面
    return [bytes(ret, encoding="utf8"), ]

在JinJa2中 特殊符號就是{{  }} or {%  %}

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="x-ua-compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Title</title>
</head>
<body>
    <h1>姓名:{{name}}</h1>
    <h1>愛好:</h1>
    <ul>
        {% for hobby in hobby_list %}
        <li>{{hobby}}</li>
        {% endfor %}
    </ul>
</body>
</html>

上面.py中的數據是咱們手動寫的

固然咱們也能夠從數據庫中獲取數據,可是前提必定要配置用pymysql配置好數據庫哦

MTV和MVC框架

MVC框架

 Web服務器開發領域裏著名的MVC模式,所謂MVC就是把Web應用分爲模型(M),控制器(C)和視圖(V)三層,他們之間以一種插件式的、鬆耦合的方式鏈接在一塊兒,模型負責業務對象與數據庫的映射(ORM),視圖負責與用戶的交互(頁面),控制器接受用戶的輸入調用模型和視圖完成用戶的請求,其示意圖以下所示:

MTV框架

 Django的MTV模式本質上和MVC是同樣的,也是爲了各組件間保持鬆耦合關係,只是定義上有些許不一樣,Django的MTV分別是指:

  • M 表明模型(Model): 負責業務對象和數據庫的關係映射(ORM)。
  • T 表明模板 (Template):負責如何把頁面展現給用戶(html)。
  • V 表明視圖(View):   負責業務邏輯,並在適當時候調用Model和Template。

  除了以上三層以外,還須要一個URL分發器,它的做用是將一個個URL的頁面請求分發給不一樣的View處理,View再調用相應的Model和Template,MTV的響應模式以下所示:

  

  通常是用戶經過瀏覽器向咱們的服務器發起一個請求(request),這個請求回去訪問視圖函數,(若是不涉及到數據調用,那麼這個時候視圖函數返回一個模板也就是一個網頁給用戶),視圖函數調用模型,模型去數據庫查找數據,而後逐級返回,視圖函數把返回的數據填充到模板中空格中,最後返回網頁給用戶。

django:下載安裝&建立啓動

1.下載django

pip3 install django==1.11.9

2.建立一個django的project

django-admin startproject mysite   # 建立了一個名爲"mysite"的Django 項目:

當咱們執行完這條指令後 ,會出現以下一堆文件

這些文件的做用:

  • manage.py ----- Django項目裏面的工具,經過它能夠調用django shell和數據庫,啓動關閉項目與項目交互等,無論你將框架分了幾個文件,必然有一個啓動文件,其實他們自己就是一個文件。
  • settings.py ---- 包含了項目的默認設置,包括數據庫信息,調試標誌以及其餘一些工做的變量。
  • urls.py ----- 負責把URL模式映射到應用程序。
  • wsgi.py ---- runserver命令就使用wsgiref模塊作簡單的web server,後面會看到renserver命令,全部與socket相關的內容都在這個文件裏面了,目前不須要關注它。

3.建立django APP應用

剛纔咱們只是建立了一個django項目,可是裏面並無以前所提到的models.py views.py這些文件

這是由於咱們只是建立了django項目,並無建立一個django的app

因此這個app須要咱們執行一條指令去建立

python manage.py startapp blog2  #建立一個django應用 每一個應用的目錄下都有本身的views.py視圖函數和models.py數據庫操做相關的文件

當咱們執行完這條指令後,會發現文件夾多了幾個文件

  

咱們如今只須要看其中兩個文件

    models.py :以前咱們寫的那個名爲model的文件就是建立表用的,這個文件就是存放與該app(應用)相關的表結構的

    views.py    :存放與該app相關的視圖函數的

      其餘的先不用管,之後會知道的

4.啓動django項目

python manage.py runserver 8080   # python manage.py runserver 127.0.0.1:8080,本機就不用寫ip地址了 若是連端口都沒寫,默認是本機的8000端口

這樣咱們的django就啓動起來了。當咱們訪問:http://127.0.0.1:8080/時就能夠看到:

       

這是django裏本身寫的一個html文件,當看到這個頁面就說明,咱們的django啓動成功了

相關文章
相關標籤/搜索