您好,登錄后才能下訂單哦!
# 學習《Flask Web開發(fā):基于Python的Web應用開發(fā)實戰(zhàn)》分享
- 一直在說學習Python,對同事,對朋友,都說我正在學習Python,這無形給自己一定的壓力,促使自己要去學習,進步。
- Python的語法看了忘,忘了再看。每天學習時長不固定,會造成這樣的效果。
- 然后看到這本書《Flask Web開發(fā):基于Python的Web應用開發(fā)實戰(zhàn)》,時間不長不短,也學習了一段時間,前后看了兩三遍,學會了一些知識,在這里做一個整理、分享。
- 堅持學習很重要,活到老學到老,讓我們一起學習Python吧。
- 下面從一個小項目中,分享一下。
- 小項目:采集[`廖雪峰的官方網(wǎng)站`](http://www.liaoxuefeng.com/)部分教程,并在Web中展示。
- 小項目在`Mac OS X`,`python3`中運行。(`python2`調(diào)試中)
## 1. 使用虛擬環(huán)境
- 與系統(tǒng)的Python解釋器分開,在項目中的私有副本
### 安裝
- 檢查virtualenv
```
$ virtualenv -- version
```
- 安裝virtualenv
```
$ sudo pip install virtualenv
```
- 新建一個文件夾作為項目目錄
- 按照慣例,一般虛擬環(huán)境會被命名為 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
```
- 激活這個虛擬環(huán)境
```
source venv/bin/activate
```
- 為了提醒你已經(jīng)激活了虛擬環(huán)境,激活虛擬環(huán)境的 命令會修改命令行提示符,加入環(huán)境名
```
(venv) $
```
- 回到全局 Python 解釋器
```
deactivate
```
### 使用pip安裝Python包
- pip 的 安裝請參見 [https://pip.pypa.io/en/latest/installing.html](https://pip.pypa.io/en/latest/installing.html)
- 在虛擬環(huán)境中安裝 Flask
```
(venv) $ pip install flask
```
- 嘗試導入 Flask
```
(venv) $ python
>>> import flask
>>>
```
### 第一個程序
```
from flask import Flask
app = Flask(__name__)#Flask 類的對象
'''
修飾器是 Python 語言的標準特性,可以使用不同的方式修改函數(shù)的行為。
慣常用法是使用修飾器把函數(shù)注冊為事件的處理程序
'''
#app.route 修飾器,把修飾的函數(shù)注冊為路由
@app.route('/')
def hello():
return '<h2>Hello World</h2>'
#程序會顯示一個使用 name 動態(tài)參數(shù)生成的歡迎消息
@app.route('/user/<name>')
def user(name):
return '<h2>Hello, %s!</h2>' % name
if __name__ == '__main__':#__name__=='__main__' 是 Python 的慣常用法
app.run(debug=True)#要想啟用調(diào)試模式,我們可以把 debug 參數(shù)設為 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文件夾包含數(shù)據(jù)庫遷移腳本;
- venv文件夾包含Python虛擬環(huán)境。
- pip 可以使用如下命令自動生成requirements.txt文件
- 該文件便是項目中所需要的所有Python包
```
(venv) $ pip freeze > requirements.txt
```
- 創(chuàng)建一個新的虛擬環(huán)境,并在其上運行以下命令
- 即可安裝該項目中所需要的所有Python包
```
(venv) $ pip install -r requirements.txt
```
- 創(chuàng)建遷移倉庫
```
(venv) $ python manage.py db init
```
- 創(chuàng)建遷移腳本
```
(venv) $ python manage.py db migrate -m "initial migration"
```
- 更新數(shù)據(jù)庫
```
(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. 采集數(shù)據(jù)
```
#采集頁面列表
@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)
#采集列表內(nèi)容
@manager.command
def collect_list_edit(name='liaoxuefeng'):
List.list_edit(name)
#在終端執(zhí)行
(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
#定義環(huán)境變量 或 修改config.py中配置指定數(shù)據(jù)庫
(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/
```
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。