python(Flaskベースのタスクリスト管理システム)
19896 ワード
1.目標
本プロジェクトでは、データベースのバックエンドとしてMariadb、フロントエンドのテクノロジースタックとしてBootstrapを学習し、インベントリアプリケーションを実現します.ここからFlask WebアプリケーションフレームワークとMariadbリレーショナルデータベースとBootStrap web開発フレームワークを学ぶことができます.
2.プロジェクト紹介
本アプリケーションは、TodoMVCのtodo listアプリケーションから変更され、Mariadbをデータベースのバックエンドとして使用し、BootstrapをフロントエンドのFlaskアプリケーションとして使用します.まずいい名前をつけましょう.便利になったら呼んでください.
todo list=>(カスタマイズ、任意の名前)=>todoest
一般的なtodo listアプリケーションのように、todoestは以下の機能を実現しています.管理データベース接続 すべてのtodoエントリ がリストされます.新しいtodo を作成検索単一todo 単一todoを編集するか、完了したとマークする 単一todo を削除
3.プロジェクト効果ラベルページを新規作成し、todoest を起動します.ブラウザアクセスを開くhttp://localhost:8000/
4.技術分析なぜFlaskを選んだのですか? FlaskはPythonを用いて作成された軽量級Webアプリケーションフレームワークである.WSGIツールボックスはWerkzeug、テンプレートエンジンはJinja 2を使用します.FlaskはBSDライセンスを使用します. Flaskは、単純なコアを使用し、extensionで他の機能を追加するため、「microframework」とも呼ばれています. Flaskには、デフォルトで使用されるデータベース、フォーム検証ツールはありません.したがってFlaskはPythonを用いて作成された軽量級Webアプリケーションフレームワークである.軽くて拡張しやすく、主流で、質問があっても見つからないことを恐れず、todoestという軽応用に最適です.
なぜMariadbを選んだのですか?MariaDBデータベース管理システムはMySQLの1つの分岐で、主にオープンソースコミュニティによって維持されており、GPLライセンスMariaDBを採用する目的はMySQLと完全に互換性があり、APIとコマンドラインを含め、簡単にMySQLの代替品になることができるようにすることです.MariaDBはMySQLデータベースの代替品と見なされていますが、拡張機能、ストレージエンジン、およびいくつかの新しい機能の改善においてMySQLよりも優れています.MySQLからMariaDBへの移行も簡単です. なぜBootstrapを選んだのですか? Bootstrapは、アメリカのTwitter会社のデザイナーMark OttoとJacob Thorntonが協力してHTML、CSS、JavaScriptに基づいて開発した簡潔で直感的で強力なフロントエンド開発フレームワークであり、Web開発をより迅速にする. Bootstrapには豊富なWebコンポーネントが含まれており、これらのコンポーネントに基づいて、きれいで機能的なWebサイトを迅速に構築することができます.ドロップダウンメニュー、ボタングループ、ボタンドロップダウンメニュー、ナビゲーション、ナビゲーションバー、パスナビゲーション、ページング、レイアウト、サムネイル、警告ダイアログ、進捗バー、メディアオブジェクトなどの があります.
プロジェクトの成果:
appパッケージ:
__ init __:
models(データベーステーブルテンプレート):
form(webフォーム):
views(ビュー関数):
static(静的ファイル):
templates(htmlページ):対応するビュー関数の機能に基づいて適切なhtmlページを作成し、bootstrap中国語ドキュメント上のテンプレートを通じて美しいページを作成することができます.config(プロファイル):
manage(アプリケーション):
関連する拡張
Flask-Mementローカライズ日時
1.Flask-Mementを使用する理由 Webプログラムのユーザが世界各地から来た場合,Webの世界と現地時間をどのように一致させるかを考える.サーバはユーザの地理的位置に関係なく時間単位を統一する必要があるため,協調時間(Coordinated Universal Time,UTC)が一般的に用いられる.しかし、ユーザーにとって見たいのは自分のいる現地時間であり、現地の慣用的なフォーマットを使用しています.
2.Flask-Ment実現原理?優雅な解決策は、時間単位をWebブラウザに送信し、現地時間に変換してレンダリングすることです.Webブラウザは、コンピュータのタイムゾーンと領域の設定を得ることができるため、このタスクをよりよくすることができます. JavaScriptを使用して開発された優れたクライアントオープンソースライブラリがあります.momentと呼ばれています.jsは、ブラウザで日付と時間をレンダリングできます.Flask-MentはFlaskプログラムの拡張であり、momentを使用することができます.jsはJinja 2テンプレートに統合されています.
3.具体的なコードは?それまでにflask-momentモジュール、 をインストールする必要がある.以降のappパッケージの_init__このモジュールをファイルにインポート:from flask-moment import Moment, momentのオブジェクトをインスタンス化してアプリケーションに関連付ける:moment=Moment(app) テンプレートの作成はmomentを除く.js.Flask_Momentはjqueryにも依存している.jsは、HTMLドキュメントの導入という一連のファイルを選択することで、どのバージョンを使用するか、拡張提供の補助関数を使用するか、コンテンツ配信ネットワークからテストによる追加コンテンツを導入するには、JinJa 2が提供するsuper()関数を使用する必要があります.このライブラリは、たとえば、ベーステンプレートのscriptsブロックに導入できます. ビュー関数を編集して時間を処理するために、Flask-Mementはテンプレートにmontentクラスを開きます.コードは変数current_をtime(すなわちUTC時間がテンプレート処理に伝達される)は、テンプレートに入力されてレンダリングされる.このようにしてローカル時間問題 を解決した.ページロジック を編集する参考資料Flask-Mementはmomentを実現した.jsのformat()、fromNow()、fromTime()、calendar()、valueOf()およびunix()メソッド.ドキュメントを参照してください(http://momentjs.com/docs/#/displaying/)を勉強します.jsが提供するすべてのフォーマットオプション.
Flaskとpyechartsに基づくグラフィックの可視化
1.Flask統合Echartsライブラリ
Flaskはpython webが開発したマイクロフレームワークで、Echartsのクールな機能は主にjavascriptが機能し、両者を結合し、より大きな役割を果たしています.静的要求実現ステップ1).公式サイトでEcharts 2)をダウンロードします.Echarts公式サイトのドキュメントを参照するチュートリアル を導入動的要求ステップ:jsonとajax要求1を用いる).ajaxとは?AJAX=Asynchronous JavaScript and XML(非同期JavaScriptとXML).AJAXは、高速動的Webページを作成するための技術です.AJAXは、バックグラウンドでサーバと少量のデータ交換を行うことで、Webページの非同期更新を実現します.これは、Webページ全体を再ロードせずに、Webページの一部を更新できることを意味します.2). jsonって何?JSON:JavaScript Object Notation(JavaScriptオブジェクト表現).JSONはテキスト情報を格納・交換する構文である.XMLに似ています.
本プロジェクトでは、データベースのバックエンドとしてMariadb、フロントエンドのテクノロジースタックとしてBootstrapを学習し、インベントリアプリケーションを実現します.ここからFlask WebアプリケーションフレームワークとMariadbリレーショナルデータベースとBootStrap web開発フレームワークを学ぶことができます.
2.プロジェクト紹介
本アプリケーションは、TodoMVCのtodo listアプリケーションから変更され、Mariadbをデータベースのバックエンドとして使用し、BootstrapをフロントエンドのFlaskアプリケーションとして使用します.まずいい名前をつけましょう.便利になったら呼んでください.
todo list=>(カスタマイズ、任意の名前)=>todoest
一般的なtodo listアプリケーションのように、todoestは以下の機能を実現しています.
3.プロジェクト効果
4.技術分析
プロジェクトの成果:
appパッケージ:
__ init __:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_bootstrap import Bootstrap
from flask_script import Manager
from flask_migrate import Migrate
from flask_moment import Moment
import pymysql
app = Flask(__name__)
#
pymysql.install_as_MySQLdb()
#
app.config.from_pyfile('../config.py')
db = SQLAlchemy(app)
manager = Manager(app)
bt = Bootstrap(app)
migrate = Migrate(app, db)
moment = Moment(app)
models(データベーステーブルテンプレート):
from app import db
from werkzeug.security import generate_password_hash, check_password_hash
from datetime import datetime
# : , , ,
# : , ,
#
class User(db.Model):
id = db.Column(db.Integer, autoincrement=True, primary_key=True)
username = db.Column(db.String(20), unique=True)
password_hash = db.Column(db.String(100), nullable=False)
email = db.Column(db.String(30), unique=True)
add_time = db.Column(db.DateTime, default=datetime.now()) #
# 1). User todos; 2). Todo user;
todos = db.relationship('Todo', backref="user")
categories = db.relationship('Category', backref='user')
@property
def password(self):
"""u.password"""
raise AttributeError(" ")
@password.setter
def password(self, password):
"""u.password = xxxxx """
self.password_hash = generate_password_hash(password)
def verify_password(self, password):
""" """
return check_password_hash(self.password_hash, password)
def __repr__(self):
return "" %(self.username)
# :
# , ,
#
class Todo(db.Model):
id = db.Column(db.Integer, autoincrement=True, primary_key=True)
content = db.Column(db.String(100)) #
status = db.Column(db.Boolean, default=False) #
add_time = db.Column(db.DateTime, default=datetime.now()) #
# , id
category_id = db.Column(db.Integer, db.ForeignKey('category.id'))
# ;
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
def __repr__(self):
return "" %(self.content[:6])
#
class Category(db.Model):
id = db.Column(db.Integer, autoincrement=True, primary_key=True)
name = db.Column(db.String(20), unique=True)
add_time = db.Column(db.DateTime, default=datetime.now()) #
# 1). Category todos, 2). Todo category;
todos = db.relationship('Todo', backref='category')
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
def __repr__(self):
return "" %(self.name)
form(webフォーム):
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField, \
ValidationError, SelectField, DateTimeField
from wtforms.validators import DataRequired, Email, Length, EqualTo
#
from app.models import User, Category
class RegisterForm(FlaskForm):
email = StringField(
label=" ",
validators=[
DataRequired(),
Email(),
]
)
username = StringField(
label=" ",
validators=[
DataRequired(),
],
)
password = PasswordField(
label=' ',
validators=[
DataRequired(),
Length(6, 12, " 6-12 ")
]
)
repassword = PasswordField(
label=' ',
validators=[
EqualTo("password", " ")
]
)
submit = SubmitField(
label=" "
)
# *****************************************************
# validate_username , ,
def validate_username(self, field):
# filed.data ==== username
u = User.query.filter_by(username=field.data).first()
if u:
raise ValidationError(" %s " % (u.username))
def validate_email(self, filed):
u = User.query.filter_by(email=filed.data).first()
if u:
raise ValidationError(" %s " % (u.email))
#
class LoginForm(FlaskForm):
username = StringField(
label=" ",
validators=[
DataRequired(),
],
)
password = PasswordField(
label=' ',
validators=[
DataRequired(),
# Length(6, 12, " 6-12 ")
]
)
submit = SubmitField(
label=" "
)
#
class TodoForm(FlaskForm):
content = StringField(
label=" ",
validators=[
DataRequired()
]
)
#
category = SelectField(
label=" ",
coerce=int,
choices=[(item.id, item.name) for item in Category.query.all()]
)
# ( )
class AddTodoForm(TodoForm):
finish_time = DateTimeField(
label=" "
)
submit = SubmitField(
label=" ",
)
# ( )
class EditTodoForm(TodoForm):
submit = SubmitField(
label=" ",
)
views(ビュー関数):
import json
from functools import wraps
from app import app, db
from app.forms import RegisterForm, LoginForm, AddTodoForm, EditTodoForm
from flask import render_template, flash, redirect, url_for, session, request
from app.models import User, Todo
# ,
def is_login(f):
""" """
@wraps(f)
def wrapper(*args, **kwargs):
# session seesion['user'],
# , , ;
# , , ;;
if session.get('user', None):
return f(*args, **kwargs)
else:
flash(" %s" % (f.__name__))
return redirect(url_for('login'))
return wrapper
#
@app.route('/')
def index():
return redirect(url_for('list'))
#
@app.route('/register/', methods=['POST', 'GET'])
def register():
form = RegisterForm()
if form.validate_on_submit():
# 1. ;
email = form.email.data
username = form.username.data
password = form.password.data
# 2. ? None, ;
u = User.query.filter_by(username=username).first()
if u:
flash(" %s " % (u.username))
return redirect(url_for('register'))
else:
u = User(username=username, email=email)
u.password = password
db.session.add(u)
db.session.commit()
flash(" %s " % (u.username))
return redirect(url_for('login'))
return render_template('register.html',
form=form)
#
@app.route('/login/', methods=['GET', 'POST'])
def login():
form = LoginForm()
if form.validate_on_submit():
username = form.username.data
password = form.password.data
# 1. ?
u = User.query.filter_by(username=username).first()
if u and u.verify_password(password):
session['user_id'] = u.id
session['user'] = u.username
flash(" !")
return redirect(url_for('index'))
else:
flash(" !")
return redirect(url_for('login'))
return render_template('login.html',
form=form)
#
@app.route('/logout/')
@is_login
def logout():
session.pop('user_id', None)
session.pop('user', None)
return redirect(url_for('login'))
#
@app.route('/todo/add/', methods=['GET', 'POST'])
@is_login
def todo_add():
form = AddTodoForm()
if form.validate_on_submit():
#
content = form.content.data
category_id = form.category.data
#
# ,
todo = Todo(content=content,
category_id=category_id,
user_id=session.get('user_id'))
db.session.add(todo)
db.session.commit()
flash(" ")
return redirect(url_for('todo_add'))
return render_template('todo/add_todo.html',
form=form)
#
@app.route('/todo/edit//', methods=['GET', 'POST'])
@is_login
def todo_edit(id):
form = EditTodoForm()
# ***** : , ;
todo = Todo.query.filter_by(id=id).first()
form.content.data = todo.content
form.category.data = todo.category_id
if form.validate_on_submit():
# request.form , form.content.data ;
# print(request.form)
# content = form.content.data # error
# category_id = form.category.data # error
content = request.form.get('content')
category_id = request.form.get('category')
#
todo.content = content
todo.category_id = category_id
db.session.add(todo)
db.session.commit()
flash(" ")
return redirect(url_for('list'))
return render_template('todo/edit_todo.html',
form=form)
# : id
@app.route('/todo/delete//')
@is_login
def todo_delete(id):
todo = Todo.query.filter_by(id=id).first()
db.session.delete(todo)
db.session.commit()
flash(" ")
return redirect(url_for('list'))
#
@app.route('/todo/list/')
@app.route('/todo/list//')
@is_login
def list(page=1):
#
# Todo.query.paginate(page, per_page=5)
todoPageObj = Todo.query.filter_by(user_id=session.get('user_id')).paginate(page, per_page=app.config['PER_PAGE']) # config.py ;
return render_template('todo/list_todo.html',
todoPageObj=todoPageObj,
)
#
@app.route('/todo/done//')
@is_login
def done(id):
todo = Todo.query.filter_by(id=id).first()
todo.status = True
db.session.add(todo)
db.session.commit()
flash(" ")
return redirect(url_for('list'))
#
@app.route('/todo/undo/')
@is_login
def undo(id):
todo = Todo.query.filter_by(id=id).first()
todo.status = False
db.session.add(todo)
db.session.commit()
flash(" ")
return redirect(url_for('list'))
@app.route('/showTodo/')
@is_login
def showTodo():
done_count = Todo.query.filter_by(status=True).count()
undone_count = Todo.query.filter_by(status=False).count()
return render_template('todo/show_todo.html',
info={
' ': done_count,
' ': undone_count
})
# echarts
@app.route('/newShowTodo/')
@is_login
def newShowTodo():
return render_template('todo/new_show_todo.html')
# ajax
# screpts ,
# python js json
@app.route('/get_data/')
@is_login
def get_data():
done_count = Todo.query.filter_by(status=True).count()
undone_count = Todo.query.filter_by(status=False).count()
info = {
'info': [" ", " "],
'count': [done_count, undone_count]
}
# ensure_ascii=False,
return json.dumps(info, ensure_ascii=False)
# cup
@app.route('/disk/')
def get_disk():
import psutil
cpuInfo = json.dumps({'CPU ', psutil.cpu_percent()},
ensure_ascii=False)
return cpuInfo
static(静的ファイル):
# css main.css:
.navbar {
font-size: 130%;
background: whitesmoke;
margin-top: 10px;
padding-top: 5px;
box-shadow: 2px 2px 2px 2px lightgray;
height: 60px;
}
# js echarts.min.js :
templates(htmlページ):対応するビュー関数の機能に基づいて適切なhtmlページを作成し、bootstrap中国語ドキュメント上のテンプレートを通じて美しいページを作成することができます.config(プロファイル):
#
SQLALCHEMY_DATABASE_URI = 'mysql://root:redhat@localhost/Todo'
SQLALCHEMY_TRACK_MODIFICATIONS = True
# , csrf( )
SECRET_KEY = 'westos'
#
PER_PAGE = 5
manage(アプリケーション):
from app import manager, db
#
from app.views import *
from flask_migrate import MigrateCommand
# ;
from app.models import User, Category, Todo
#
@manager.command
def dbinit():
""" """
db.drop_all()
db.create_all()
u = User(username='admin', email="[email protected]")
u.password = 'admin'
db.session.add(u)
db.session.commit()
print(" %s ......." % (u.username))
c = Category(name=" ", user_id=1)
db.session.add(c)
print(" %s ...." % (c.name))
t = Todo(content=" Flask", category_id=1, user_id=1)
db.session.add(t)
print(" %s ....." % (t.content))
db.session.commit()
#
manager.add_command('db', MigrateCommand)
if __name__ == '__main__':
manager.run()
関連する拡張
Flask-Mementローカライズ日時
1.Flask-Mementを使用する理由
2.Flask-Ment実現原理?
3.具体的なコードは?
# moment
{% block script %}
{{ super()}}
{{ monent.include_moment()}}
{% endblock %}
@app.route('/')
def index():
return render_template('index.html',
current_time=datetime.utcnow())
The local date and time is {{ moment(current_time).format('LLL') }}.
That was {{ moment(current_time).fromNow(refresh=True) }}.
Flaskとpyechartsに基づくグラフィックの可視化
1.Flask統合Echartsライブラリ
Flaskはpython webが開発したマイクロフレームワークで、Echartsのクールな機能は主にjavascriptが機能し、両者を結合し、より大きな役割を果たしています.
# ajax url
#
@app.route('/getdata')
def get_data():
language = ['python', 'java', 'c', 'c++', 'c#', 'php']
value = ['100', '150', '100', '90', '80', '90']
return json.dumps({'language':language,'value':value},ensure_ascii=False)
# , ensure_ascii=False
# scripts ,$(function() {}); $(document).ready(function(){ })
$(function () {
// dom, echarts
var myChart = echarts.init(document.getElementById('main'));
$.ajax({
url:'/getdata',
success:function (data) {
# python json ;
json_data=JSON.parse(data)
console.info(json_data['language'])
console.info(json_data['value'])
//
var option = {
title: {
text: ' '
},
tooltip: {},
legend: {
data:[' ']
},
xAxis: {
data: json_data['language']
},
yAxis: {},
series: [{
name: ' ',
type: 'bar',
data: json_data['value']
}]
};
// 。
myChart.setOption(option);
}
})
})