學習《Flask Web開發:基於Python的Web應用開發實戰》分享

# 學習《Flask Web開發:基於PythonWeb應用開發實戰》分享


- 一直在說學習Python,對同事,對朋友,都說我正在學習Python,這無形給自己一定的壓力,促使自己要去學習,進步。

- Python的語法看了忘,忘了再看。每天學習時長不固定,會造成這樣的效果。

- 然後看到這本書《Flask Web開發:基於PythonWeb應用開發實戰》,時間不長不短,也學習了一段時間,前後看了兩三遍,學會了一些知識,在這裏做一個整理、分享。

- 堅持學習很重要,活到老學到老,讓我們一起學習Python吧。


- 下面從一個小項目中,分享一下。

- 小項目:採集[`廖雪峯的官方網站`](http://www.liaoxuefeng.com/)部分教程,並在Web中展示。

- 小項目在`Mac OS X``python3`中運行。(`python2`調試中)


## 1. 使用虛擬環境


- 與系統的Python解釋器分開,在項目中的私有副本


### 安裝


- 檢查virtualenv


```

$ virtualenv -- version

```


- 安裝virtualenv


```

$ sudo pip install virtualenv

```


- 新建一個文件夾作爲項目目錄

- 按照慣例,一般虛擬環境會被命名爲 venv


```

virtualenv venv

New python executable in venv/bin/python

Installing distribute......done.

Installing pip.............done.

```


- 可指定python版本


```

virtualenv venv --python=python2.7

virtualenv venv --python=python3.5

```


- 激活這個虛擬環境


```

source venv/bin/activate

```


- 爲了提醒你已經激活了虛擬環境,激活虛擬環境的 命令會修改命令行提示符,加入環境名


```

(venv) $

```


- 回到全局 Python 解釋器


```

deactivate

```


### 使用pip安裝Python


- pip 安裝請參見 [https://pip.pypa.io/en/latest/installing.html](https://pip.pypa.io/en/latest/installing.html)

- 在虛擬環境中安裝 Flask


```

(venv) $ pip install flask

```


- 嘗試導入 Flask


```

(venv) $ python

>>> import flask

>>>

```


### 第一個程序


```

from flask import Flask


app = Flask(__name__)#Flask 類的對象


'''

修飾器是 Python 語言的標準特性,可以使用不同的方式修改函數的行爲。

慣常用法是使用修飾器把函數註冊爲事件的處理程序

'''

#app.route 修飾器,把修飾的函數註冊爲路由

@app.route('/')

def hello():

    return '<h1>Hello World</h1>'


#程序會顯示一個使用 name 動態參數生成的歡迎消息

@app.route('/user/<name>')

def user(name):

    return '<h1>Hello, %s!</h1>' % name


if __name__ == '__main__':#__name__=='__main__' Python 的慣常用法

    app.run(debug=True)#要想啓用調試模式,我們可以把 debug 參數設爲 True


```


### 運行


```

#保存以上程序至上述項目根目錄 hello.py

(venv) $ python hellp.py

 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

 * Restarting with stat

 * Debugger is active!

 * Debugger PIN: 277-775-896

#訪問 http://127.0.0.1:5000/ http://127.0.0.1:5000/user/Python 即可

```


## 2. 初始項目結構


```

|-flasky

    |-app/

        |-templates/

        |-static/

        |-main/

            |-__init__.py

            |-errors.py

            |-forms.py

            |-views.py

        |-collect/

            |-__init__.py

        |-__init__.py

        |-models.py

    |-migrations/

    |-venv/

    |-requirements.txt

    |-config.py

    |-manage.py

```


- Flask 程序一般都保存在名爲 app 的包中;

- migrations文件夾包含數據庫遷移腳本;

- venv文件夾包含Python虛擬環境。


- pip 可以使用如下命令自動生成requirements.txt文件

- 該文件便是項目中所需要的所有Python


```

(venv) $ pip freeze > requirements.txt

```


- 創建一個新的虛擬環境,並在其上運行以下命令

- 即可安裝該項目中所需要的所有Python


```

(venv) $ pip install -r requirements.txt

```


- 創建遷移倉庫


```

(venv) $ python manage.py db init

```


- 創建遷移腳本


```

(venv) $ python manage.py db migrate -m "initial migration"

```


- 更新數據庫


```

(venv) $ python manage.py db upgrade <revision>

```


- 啓動腳本


```

(venv) $ python manage.py runserver

```



## 3. 定義模型


```

from datetime import datetime

from . import db

from sqlalchemy.dialects.mysql import TINYINT, LONGTEXT

from .collect import create_collect



class Index(db.Model):

    __tablename__ = 'indexs'

    id = db.Column(db.Integer, primary_key=True)

    name = db.Column(db.String(64))

    url = db.Column(db.String(255))

    html = db.Column(LONGTEXT)

    status = db.Column(TINYINT(3), default=0)

    dateline = db.Column(db.DateTime(), default=datetime.utcnow)

    lists = db.relationship('List', backref='list', lazy='dynamic')


    def __repr__(self):

        return '<Index %r>' % self.name



class List(db.Model):

    __tablename__ = 'lists'

    id = db.Column(db.Integer, primary_key=True)

    index_id = db.Column(db.Integer, db.ForeignKey('indexs.id'))

    name = db.Column(db.String(64))

    url = db.Column(db.String(255))

    html = db.Column(LONGTEXT)

    status = db.Column(TINYINT(3), default=0)

    dateline = db.Column(db.DateTime(), default=datetime.utcnow)


    def __repr__(self):

        return '<List %r>' % self.name


```


## 4. 採集數據


```

#採集頁面列表

@manager.command

def collect_index(name='liaoxuefeng'):

    Index.index_add(name)

    Index.index_edit(name)


#採集列表頁面

@manager.command

def collect_list_add(name='liaoxuefeng'):

    List.list_add(name)


#採集列表內容

@manager.command

def collect_list_edit(name='liaoxuefeng'):

    List.list_edit(name)


#在終端執行


(venv) $ python manage.py collect_index <name>

```


## 5. 定義路由


```

#首頁 採集頁面列表

@main.route('/')

def index():

    pass


#添加採集頁面

@main.route('/index_add', methods=['GET', 'POST'])

def index_add():

    pass


#編輯採集頁面

@main.route('/index_edit/<int:id>', methods=['GET', 'POST'])

def index_edit(id):

    pass


#刪除添加採集頁面

@main.route('/index_delete/<int:id>')

def index_delete(id):

    pass


#採集頁面下的列表頁面

@main.route('/index/<int:id>/list')

def index_list(id):

    pass


#列表頁面

@main.route('/list')

def list_list():

    pass


#添加列表頁面

@main.route('/list_add', methods=['GET', 'POST'])

def list_add():

    pass


#編輯列表頁面

@main.route('/list_edit/<int:id>', methods=['GET', 'POST'])

def list_edit(id):

    pass


#刪除列表頁面

@main.route('/list_delete/<int:id>')

def list_delete(id):

    pass


#詳細頁面

@main.route('/list_view/<int:id>')

def list_view(id):

    pass


```


## 6. CRUD


```

from flask_wtf import FlaskForm

from wtforms import StringField, SelectField, RadioField, TextAreaField, SubmitField

from wtforms.validators import Required, Length, URL

from wtforms import ValidationError

from ..models import Index, List



class IndexForm(FlaskForm):

    name = StringField('Name', validators=[Length(0, 64)])

    url = StringField('Url', validators=[Required(), Length(1, 255), URL()])

    html = TextAreaField('Html')

    status = RadioField('Status', coerce=int, default='0')

    submit = SubmitField('Submit')


    def __init__(self, index=None, *args, **kwargs):

        super(IndexForm, self).__init__(*args, **kwargs)

        self.status.choices = [(0, 'Initial'), (1, 'Downloaded'), (2, 'Deprecated')]

        self.index = index


    def validate_url(self, field):

        if self.index is None:

            if Index.query.filter_by(url=field.data).first():

                raise ValidationError('Url already in use.')

        else:

            if self.index.url != field.data and \

                    Index.query.filter_by(url=field.data).first():

                raise ValidationError('Url already in use.')



class ListForm(FlaskForm):

    index_id = SelectField('Index id', coerce=int)

    name = StringField('Name', validators=[Length(0, 64)])

    url = StringField('Url', validators=[Required(), Length(1, 255), URL()])

    html = TextAreaField('Html')

    status = RadioField('Status', coerce=int, default=0)

    submit = SubmitField('Submit')


    def __init__(self, item=None, *args, **kwargs):

        super(ListForm, self).__init__(*args, **kwargs)

        self.index_id.choices = [(index.id, index.name) for index in Index.query.filter_by(status=1).all()]

        self.status.choices = [(0, 'Initial'), (1, 'Downloaded'), (2, 'Deprecated')]

        self.item = item


    def validate_url(self, field):

        if self.item is None:

            if List.query.filter_by(url=field.data).first():

                raise ValidationError('Url already in use.')

        else:

            if self.item.url != field.data and \

                    List.query.filter_by(url=field.data).first():

                raise ValidationError('Url already in use.')



```


## 7.運行


- 本項目代碼存放在github [https://github.com/bstdn/flask_collect](https://github.com/bstdn/flask_collect)


```

#運行項目

git clone https://github.com/bstdn/flask_collect.git

cd flask_collect

virtualenv venv

source venv/bin/activate

(venv) $ pip install -r requirements.txt


#定義環境變量 修改config.py中配置指定數據庫

(venv) $ export SECRET_KEY=<SECRET_KEY>

(venv) $ export DEV_DATABASE_URL=<DEV_DATABASE_URL>


(venv) $ python manage.py db upgrade

(venv) $ python manage.py collect_index

(venv) $ python manage.py collect_list_add

(venv) $ python manage.py collect_list_edit

(venv) $ python manage.py runserver


#訪問 http://127.0.0.1:5000/

```


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章