成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

從零開始用 Flask 搭建一個網(wǎng)站(二)

Coly / 1904人閱讀

摘要:從零開始用搭建一個網(wǎng)站一介紹了如何搭建環(huán)境,以及應(yīng)用基本項目結(jié)構(gòu)。我們要搭建的網(wǎng)站是管理第三方集成的控制臺,類似于。我們先定義一個用戶模型然后在文件夾下創(chuàng)建一個文件。

從零開始用 Flask 搭建一個網(wǎng)站(一) 介紹了如何搭建 Python 環(huán)境,以及 Flask 應(yīng)用基本項目結(jié)構(gòu)。我們要搭建的網(wǎng)站是管理第三方集成的控制臺,類似于 Slack。 本篇主要講解數(shù)據(jù)如何在 Flask 應(yīng)用中流動,其它的框架基本上也是大同小異。

數(shù)據(jù)庫

既然是數(shù)據(jù)的流動,首先要建立起存取數(shù)據(jù)的地方,也就是數(shù)據(jù)庫了(這里是指關(guān)系型數(shù)據(jù)庫,NoSQL 不在這討論)。第一節(jié)中我們使用了 Flask-SQLAlchemy 管理數(shù)據(jù)庫,在 Flask-SQLAlchemy 中,數(shù)據(jù)庫使用 URL 指定,最流行的數(shù)據(jù)庫 URL 格式如下:

在 config.py 中我們已經(jīng)指定了數(shù)據(jù)庫 URL,如果使用云平臺部署程序,直接將生成的數(shù)據(jù)庫 URL 寫到 config.py 中 SQLALCHEMY_DATABASE_URI 即可。這里我們使用的是 SQLite 數(shù)據(jù)庫。Flask-SQLAlchemy 采用數(shù)據(jù)庫抽象層來操作數(shù)據(jù)庫,也稱為對象關(guān)系映射(Object-Relational Mapper, ORM),在用戶不知不覺的情況下把高層的面向?qū)ο蟛僮鬓D(zhuǎn)換成低層的數(shù)據(jù)庫指令,因此易用性好。我們已經(jīng)在 app/__init__.py 中實例化了 SQLAlchemy 類:

app/__init__.py

from flask_sqlalchemy import SQLAlchemy
...
db = SQLAlchemy()
...

定義模型

模型類可以理解為數(shù)據(jù)庫中的一張表,F(xiàn)lask-SQLAlchemy 提供了一個基類和一系列輔助類和函數(shù)來讓我們定義模型的結(jié)構(gòu)。我們直接在 app 文件夾下創(chuàng)建一個 models.py 文件。鑒于每個網(wǎng)站需求都不一樣,所存的數(shù)據(jù)也不同,但本質(zhì)上是大同小異的。這里以筆者網(wǎng)站需求為例,需要創(chuàng)建 Developer,Integration 和 Channel 三個表。

app/models.py 部分代碼

from flask import current_app
from app import db

class Developer(db.Model):    
    __tablename__ = "developers"    
    id = db.Column(db.Integer, primary_key=True)    
    dev_key = db.Column(db.String(40), unique=True, index=True)    
    platform = db.Column(db.String(50))    
    platform_id = db.Column(db.String(40), unique=True)    
    username = db.Column(db.String(150), index=True)    
    integrations = db.relationship("Integration", backref="developer")    
    channels = db.relationship("Channel", backref="developer")

class Integration(db.Model):    
    __tablename__ = "integrations"    
    id = db.Column(db.Integer, primary_key=True)    
    integration_id = db.Column(db.String(40), unique=True)    
    name = db.Column(db.String(100))    
    description = db.Column(db.String(150))    
    icon = db.Column(db.String(150))    
    channel = db.Column(db.String(150))    
    token = db.Column(db.String(150))    
    developer_id = db.Column(db.Integer, db.ForeignKey("developers.id"))

class Channel(db.Model):    
    __tablename__ = "channels"    
    id = db.Column(db.Integer, primary_key=True)    
    developer_id = db.Column(db.Integer, db.ForeignKey("developers.id"))    
    channel = db.Column(db.String(150))    

    def __repr__(self):        
        return "" % self.channel

上面的每個 Class 都繼承了 Model 類,因此每個類在數(shù)據(jù)庫中都體現(xiàn)為一張表,表名用 tablename 表示,一般用復(fù)數(shù)形式。這里主要講一下一對多的關(guān)系。可以看到上面 Developer 和 Integration 及 Channel 都有一個一對多的關(guān)系,一個用戶可以有多個集成及多個頻道。 看到這兩句:

integrations = db.relationship("Integration", backref="developer")
developer_id = db.Column(db.Integer, db.ForeignKey("developers.id"))

第一句表明添加到 Developer 表的 integrations 屬性表示這個關(guān)系的面向?qū)ο笠暯?,對于一個 Developer 實例,integrations 屬性將返回與 Developer 相關(guān)的所有 Integration,db.relationship() 第一個參數(shù)表明關(guān)系的另一端是哪個模型,backref 參數(shù)向 Integration 添加一個 developer 屬性,從而定義反向關(guān)系。第二句是在 Integration 表中創(chuàng)建一個 developer_id 字段,這個字段被定義為外鍵,就是這個外鍵建立起了關(guān)系。傳給 db.ForeignKey() 的參數(shù) "developers.id" 表明這列的值是 developers 表中行的 id 值。另外,__repr__() 方法返回一個具有可讀性的字符串表示模型,可以在調(diào)加粗文字試和測試時使用。下面我們就在命令行中操作一下數(shù)據(jù)庫。
首先執(zhí)行:

//創(chuàng)建 migrations 文件夾及相關(guān)文件
python manage.py db init

然后執(zhí)行 :

//自動創(chuàng)建遷移腳本
python manage.py db migrate
//創(chuàng)建數(shù)據(jù)表或者升級到最新版本
python manage.py db upgrade

以后模型類有改動,比如刪除或添加列,都要執(zhí)行這兩個命令,更新數(shù)據(jù)庫表?,F(xiàn)在在項目目錄下應(yīng)該自動生成了名為 dev 的數(shù)據(jù)庫。
接下來執(zhí)行如下命令進入 Python Shell:

python manage.py shell

創(chuàng)建表

使用 db.create_all() 就可以根據(jù)模型類創(chuàng)建表。如圖:

使用 db.drop_all() 方法就可以刪除所有的表,但是這種方式比較粗暴,所有的數(shù)據(jù)也一同銷毀了。

插入行

以下命令在數(shù)據(jù)庫表中插入了一條數(shù)據(jù):

通過數(shù)據(jù)庫會話 db.session 來管理對數(shù)據(jù)庫所做的改動,在準備把對象寫入數(shù)據(jù)庫之前,首先要添加到會話中,然后用 commit() 方法提交會話。接下來我們繼續(xù)插入一條 Integration 數(shù)據(jù):

>>>from app.models import Integration,Channel
>>>integration = Integration(integration_id="i0001",name="github",description="first >>>application",channel="github_event",developer=developer)
>>> db.session.add(integration)
>>> db.session.commit()

注意上面的 developer 屬性,正是我們在 models.py 中 Developer 模型中定義的一對多關(guān)系 integrations 屬性的 backref 值, 所謂的反向關(guān)系即指在 Integration 表中每條數(shù)據(jù)都有一個 developer 屬性指向 Developer 表中的某條數(shù)據(jù),這是一對多關(guān)系的高級表示。現(xiàn)在可以用 developer.integrations 來查看該 developer 擁有的哪些集成,運行截圖如下:

修改行

在提交數(shù)據(jù)庫會話之前,改變對象的某個屬性然后再提交即可更新行數(shù)據(jù)。如:

>>> developer.username = "lisi"
>>> db.session.add(developer)
>>> db.session.commit()

運行截圖:

刪除行

調(diào)用 db.session.delete() 方法即可刪除行:

>>>db.session.delete(developer)
>>>db.session.commit()

查詢行

Flask-SQLAlchemy 為每個模型提供了 query 對象,最基本的查詢是返回表中的所有記錄:

>>>Developer.query.all()

使用過濾器可以進行更精確的查詢:

>>>Developer.query.filter_by(platform="qq").all()

如果你退出了 shell 會話,前面創(chuàng)建的對象就不會以 Python 對象的形式存在,而是作為各自數(shù)據(jù)庫表中的行。這時需要重數(shù)據(jù)庫中讀取行,再重新創(chuàng)建 Python 對象,如:

>>> new_developer = Developer.query.filter_by(dev_key=12345).first()

注意上面的 first() 方法,如果不加上,將返回一個 BaseQuery 對象,這樣就不能直接用 new_developer 來訪問它的屬性值。

在視圖函數(shù)中操作數(shù)據(jù)庫

上面介紹的所有數(shù)據(jù)庫操作可以直接在視圖函數(shù)中進行。假設(shè)我們要做一個簡陋的注冊功能,下面我們就來看看如何從網(wǎng)頁中獲取數(shù)據(jù)并保存在數(shù)據(jù)庫中。我們先定義一個用戶模型:

app/models.py

class User(db.model):
    __tablename__ = "users"
    id = db.column(db.Integer, primary_key=True)
    username = db.column(db.String(50), unique=True)
    password = db.column(db.String(100))

    def __repr__(self):
        return ""  % self.username

然后在 main 文件夾下創(chuàng)建一個 forms.py 文件。

app/main/forms.py

from flask_wtf import Form
from wtforms import StringField, SubmitField, PasswordField
from wtforms.validators import DataRequired

class UserForm(Form):      
    username = StringField("Input your username", validators=[DataRequired()])    
    password = PasswordField("Input your password", validators=[DataRequired()])    
    submit = SubmitField("Submit")

我們使用了 flask-wtf 擴展(pip install flask-wtf)來處理表單。
然后我們用在 index 頁面中顯示這個表單。

index.html

{% extends "bootstrap/base.html" %}
{% import "bootstrap/wtf.html" as wtf %}

{% block title %}注冊{% endblock %}

{% block content %}
    {% for message in get_flashed_messages() %}    
        
{{ message }}
{% endfor %}
{{ wtf.quick_form(form) }}
{% endblock %}

現(xiàn)在回到 views.py 中,在我們的視圖函數(shù)中作如下改動:

app/main/views.py

...
from .forms import UserForm
from ..models import User
from app import db


@main.route("/", methods=["GET", "POST"])
def signin():
    form = UserForm()
    if form is None:
        flash("Should input username and password")
    elif  form.validate_on_submit():
        user = User(username=form.username.data, password=form.password.data)
        db.session.add(user)
        try:
            db.session.commit()
            flash("User created !")
        except:
            db.session.rollback()
            flash("User create failed")
    return render_template("index.html", form=form)

接下來我們運行一下這個小試驗:

python manage.py runserver

總結(jié)

本節(jié)我們介紹了在 Flask 中是如何使用 Flask-SQLAlchemy 、Flask-Migrate來管理數(shù)據(jù)庫,并且示范了數(shù)據(jù)從網(wǎng)頁儲存到數(shù)據(jù)庫的過程,這只是最基礎(chǔ)的部分,下一節(jié)我們將探索如何在網(wǎng)頁上發(fā)送請求并且得到數(shù)據(jù),以及如何在頁面之間傳遞數(shù)據(jù)。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/8964.html

相關(guān)文章

  • 從零開始 Flask 搭建一個網(wǎng)站(三)

    摘要:從零開始用搭建一個網(wǎng)站二介紹了有關(guān)于數(shù)據(jù)庫的運用,接下來我們在完善一下數(shù)據(jù)在前端以及前端到后端之間的交互。在中有和兩個函數(shù),分別是請求成功和失敗的回調(diào)函數(shù)。作者極光為極光團隊賬號,歡迎關(guān)注原文從零開始用搭建一個網(wǎng)站三知乎專欄極光日報 從零開始用 Flask 搭建一個網(wǎng)站(二) 介紹了有關(guān)于數(shù)據(jù)庫的運用,接下來我們在完善一下數(shù)據(jù)在前端以及前端到后端之間的交互。本節(jié)涉及到前端,因此也會講解...

    mykurisu 評論0 收藏0
  • 從零開始 Flask 搭建一個網(wǎng)站(四)

    摘要:前言從零開始用搭建一個網(wǎng)站三介紹了網(wǎng)頁前端與后端前端與前端之間數(shù)據(jù)的交流。作者極光為極光團隊賬號,歡迎關(guān)注原文從零開始用搭建一個網(wǎng)站四知乎專欄極光日報 前言 從零開始用 Flask 搭建一個網(wǎng)站(三) 介紹了網(wǎng)頁前端與后端、前端與前端之間數(shù)據(jù)的交流。本節(jié)主要介紹一下如何應(yīng)用 Flask-OAuthlib, 使用 Flask-OAuthlib 就可以輕松地請求第三方應(yīng)用提供的 API 。...

    CarterLi 評論0 收藏0
  • 從零開始搭建論壇(一):Web服務(wù)器與Web框架

    摘要:服務(wù)器通過協(xié)議與客戶端通信,因此也被稱為服務(wù)器。本文標題為從零開始搭建論壇一服務(wù)器與框架本文鏈接為更多閱讀自己動手開發(fā)網(wǎng)絡(luò)服務(wù)器一自己動手開發(fā)網(wǎng)絡(luò)服務(wù)器二自己動手開發(fā)網(wǎng)絡(luò)服務(wù)器三服務(wù)器網(wǎng)關(guān)接口實現(xiàn)原理分析最佳實踐指南應(yīng)用淺談框架編程簡介 之前用 Django 做過一個小的站點,感覺Django太過笨重,于是就準備換一個比較輕量級的 Web 框架來玩玩。Web.py 作者已經(jīng)掛掉,項目好...

    dantezhao 評論0 收藏0
  • 從零開始搭建論壇():Web服務(wù)器網(wǎng)關(guān)接口

    摘要:在從零開始搭建論壇一服務(wù)器與框架中我們弄清楚了服務(wù)器應(yīng)用程序框架的概念??蚣軕?yīng)用生成狀態(tài)碼以及響應(yīng)報頭,然后將二者傳遞至,等待服務(wù)器保存。添加響應(yīng)頭,狀態(tài)碼返回響應(yīng)信息創(chuàng)建一個服務(wù)器實例目前支持的成熟服務(wù)器有很多,是相當不錯的一個。 在 從零開始搭建論壇(一):Web服務(wù)器與Web框架 中我們弄清楚了Web 服務(wù)器、Web 應(yīng)用程序、Web框架的概念。對于 Python 來說,越來越多...

    Astrian 評論0 收藏0
  • 從零開始搭建論壇(三):Flask框架簡單介紹

    摘要:我們的論壇項目就使用了該框架。此外,麥子學(xué)院也有一個入門視頻教程,一共小時的視頻教程,涵蓋開發(fā)的方方面面,包括環(huán)境的搭建,語法介紹,項目結(jié)構(gòu)的組織,全球化,單元測試等內(nèi)容。博客地址更多閱讀的機制三個框架的對比 前面兩篇文章中我們已經(jīng)了解 Web(HTTP)服務(wù)器,Web應(yīng)用程序,Web框架,WSGI這些 Python Web 開發(fā)中的概念。我們知道,Web框架通過將不同Web應(yīng)用程序中...

    Alan 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<