flask -- 任務管理專案
阿新 • • 發佈:2018-12-19
資料庫程式碼
通過flask_sqlalchemy在資料庫中建立表。 注意:再兩個表之間有關聯時,其關聯項的資料型別必須一致。 下面的程式碼時整個專案的資料庫模組,其中共生成4個表
from datetime import datetime from flask import Flask from flask_sqlalchemy import SQLAlchemy from flask_bootstrap import Bootstrap app = Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI'] = "mysql+pymysql://root:
[email protected]/Todo" app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True app.config['SECRET_KEY'] = "westos" bootstrap = Bootstrap(app) db = SQLAlchemy(app) class task(db.Model): id = db.Column(db.Integer,autoincrement=True,primary_key=True) name = db.Column(db.String(50),unique=True) add_time = db.Column(db.DateTime,default=datetime.now()) department = db.Column(db.String(50)) state = db.Column(db.Integer,db.ForeignKey('state.id')) # userlogs = db.relationship('Userlog',backref='task') def __repr__(self): return '<task:%s>' %self.name class state(db.Model): id = db.Column(db.Integer,autoincrement=True,primary_key=True) name = db.Column(db.String(100),primary_key=True) # user = db.relationship('task',backref='state') def __repr__(self): return "<state:%s>" %self.name class Userlog(db.Model): id = db.Column(db.Integer,autoincrement=True,primary_key=True) # user_id = db.Column(db.Integer,db.ForeignKey('task.id')) content = db.Column(db.String(200)) add_time = db.Column(db.DateTime,default=datetime.now()) area = db.Column(db.String(50)) ip = db.Column(db.String(200),nullable=False) class User(db.Model): id = db.Column(db.Integer,autoincrement=True,primary_key=True) user = db.Column(db.String(50),nullable=False) passwd = db.Column(db.String(100)) if __name__=="__main__": db.drop_all() db.create_all() state1 = state(name='完成') state2 = state(name='未完成') db.session.add(state1) db.session.add(state2) db.session.commit()
檢視函式模組
在後臺實現了使用者的登陸和註冊;任務的新增、刪除、修改狀態、以及按頁查的功能。
from forms import loginForm,registerForm from models import app, Userlog,User from flask import render_template, request, redirect, url_for from models import task, db # *********************************d登陸註冊的相關操作************************************ @app.route('/') def index(): return render_template('base.html') # 登陸 @app.route('/login/',methods=['GET','POST']) def login(): # 建立一個表單物件 form = loginForm() if form.validate_on_submit(): # 再資料庫中檢視使用者是否存在,如果不存在,返回的是一個0 count = User.query.filter_by(user=form.user.data).count() print(count) # 當用戶不存在時,對使用者輸入的密碼與資料庫中相應的使用者密碼進行對比 if count >= 1: u = User.query.filter_by(user=form.user.data).first() # 當輸入的密碼與 資料庫中的密碼相同時,返回到show檢視函式對應的介面,否則繼續登陸 if u.passwd == form.passwd.data: return redirect('/show/') else: return redirect(url_for('login')) # 當用戶名再資料庫中部不存在時,返回到註冊介面 else: return redirect('/register/') return render_template('login.html',form=form) # 註冊 @app.route('/register/',methods=["POST","GET"]) def register(): # 建立一個註冊的表單物件 form = registerForm() if form.validate_on_submit(): # 將表單中獲取到的物件,傳入資料庫中,並返回到登陸的介面 u = User(user=form.user.data,passwd=form.repasswd.data) db.session.add(u) db.session.commit() return redirect('/login/') return render_template('register.html',form=form) #********************************************對任務進編輯的相關操作**************************** # 新增任務 @app.route('/add/',methods=['POST','GET']) def add(): # 將從表單中獲取的資料存入到資料庫中,再跳轉到show函式對資料庫中的資料重新載入到頁面中 if request.method=='POST': name = request.form['name'] depart = request.form['depart'] print(depart) print(name) task1 =task(name=name,department=depart) db.session.add(task1) db.session.commit() # 做一個日誌記錄 userlog = Userlog(ip=request.remote_addr,area='西安',content='新增%s任務' %name) db.session.add(userlog) db.session.commit() return redirect('/show/') else: return render_template('index.html') # 刪除任務 @app.route('/delete<int:id>/') def delete(id): # 主要思路:先在資料庫中對資料進行刪除,然後再通過show函式重新載入到頁面中。 # 村數庫中獲取要刪除的物件 t = task.query.filter_by(id=id).first() print(t) # 對獲取到的物件進行刪除 db.session.delete(t) db.session.commit() # 對對刪除操作進行一個日誌記錄 userlog = Userlog(ip=request.remote_addr, area='西安', content='刪除%s任務' %(t.name)) db.session.add(userlog) db.session.commit() return redirect('/show/') @app.route('/show/') @app.route('/show<int:page>/') def show(page=1): # 對所有任務進行分頁顯示,再html檔案中對進行操作 # form 是一個物件 form = task.query.paginate(page,5) return render_template('index.html',form=form) # 修改任務的狀態 當任務未完成時,t.state = 2;完成時,t.state = 1,然後,再html檔案中再對state進行判斷,分別顯示不同的按鈕 @app.route('/undo<int:id>/') def undo(id): t = task.query.filter_by(id=id).first() t.state = 2 db.session.add(t) db.session.commit() return redirect('/show/') @app.route('/do<int:id>/') def do(id): t = task.query.filter_by(id=id).first() t.state = 1 db.session.add(t) db.session.commit() return redirect('/show/'
登陸註冊的表單
from flask_wtf import FlaskForm
from wtforms import SubmitField,StringField,PasswordField
from wtforms.validators import length,DataRequired,equal_to
class loginForm(FlaskForm):
user = StringField(
label='手機號/郵箱',
validators=[
length(6)
]
)
passwd = PasswordField(
label='密碼',
validators=[
length(6)
]
)
submit = SubmitField(
label='提交'
)
class registerForm(FlaskForm):
user = StringField(
label='手機號/郵箱',
validators=[
length(6)
]
)
passwd = PasswordField(
label='密碼',
validators=[
length(6)
]
)
repasswd = PasswordField(
label='確認密碼',
validators=[
equal_to('passwd')
]
)
submit = SubmitField(
label='提交'
執行函式
from view import *
from models import app
if __name__ == '__main__':
app.run()
相關的templates中的檔案
- 登陸(login.html)
{% extends 'base.html' %}
{% import 'bootstrap/wtf.html' as wtf %}
{% block content %}
<div class="col-md-offset-0">
{{ wtf.quick_form(form) }}
</div>
{% endblock %}
- 註冊(register.html)
{% extends 'base.html' %}
{% import 'bootstrap/wtf.html' as wtf %}
{% block content %}
<div class="col-lg-6 col-lg-offset-4">
{{ wtf.quick_form(form) }}
</div>
{% endblock %}
- (base.html)
{% extends "bootstrap/base.html" %}
{% block navbar %}
<nav class="navbar navbar-default" role="navigation">
<div class="container-fluid" style="padding-top: 10px">
<span>
<a href="#" style="font-size: larger">任務管理</a>
</span>
<span style="float:right">
<input type="text" value="search">
<input type="submit" value="查詢">
<input type="submit" value="退出">
</span>
</div>
</nav>
{% endblock %}
{% block content %}
{% endblock %}
- 顯示(index.html)
{% extends 'base.html' %}
{% block content %}
<form class="form-inline" role="form" method="POST" action="/add/">
<div class="form-group" style="text-align: center">
<label class="sr-only" for="name">名稱</label>
<input type="text" class="form-control" id="name" placeholder="請輸入名稱" name="name">
</div>
<div class="form-group" style="text-align: center">
<label class="sr-only" for="name">名稱</label>
<select name="depart">
<option>開發部</option>
<option>市場部</option>
<option>運維部</option>
<option>銷售部</option>
</select>
</div>
<button type="submit" class="btn btn-default">提交</button>
</form>
<table class="table table-bordered">
<caption>條紋表格佈局</caption>
<thead>
<tr>
<th>編號</th>
<th>任務</th>
<th>新增時間</th>
<th>所屬部門</th>
<th>狀態</th>
<th>操作</th>
</tr>
</thead>
{% for i in form.items %}
<tr>
<td>{{ i.id }}</td>
<td>{{ i.name }}</td>
<td>{{ i.add_time }}</td>
<td>{{ i.department }}</td>
<td>
{% if i.state==1 %}
<a href="{{ url_for('undo',id=i.id) }}"><button type="button" class="btn btn-primary">完成</button></a>
{% else %}
<a href="{{ url_for('do',id=i.id) }}"><button type="button" class="btn btn-warning">未完成</button></a>
{% endif %}
</td>
<td>
<!-- 表示一個危險的或潛在的負面動作 -->
<a href="{{ url_for('delete',id=i.id) }}"> <button type="button" class="btn btn-danger">刪除</button></a>
</td>
</tr>
{% endfor %}
</table>
{% from 'macro_page.html' import paginate %}
{{ paginate('show',todos=form) }}
{% endblock %}
- 分頁的巨集(macro_page.html)
{% macro paginate(fname,todos) %}
{#定義一個函式#}
{#todos是views函式中傳遞過來的pageinate建立的物件#}
<ul class="pagination">
{#判斷是否有上一頁,如果有上一頁,則跳轉到上一頁,#}
{#has_prev方法是否有上一頁#}
{% if todos.has_prev %}
<li><a href="{{ url_for(fname,page=todos.prev_num) }}">上一頁</a></li>
{% else %}
<li class="disabled"><a href="#">上一頁</a></li>
{% endif %}
{# iter_pages返回的是一個迭代器物件,依次遍歷#}
{% for page in todos.iter_pages(right_current=2) %}
{% if page == todos.page %}
{# todos.page:代表使用者輸入的頁數#}
<li class="active"><a href={{ url_for(fname,page=page) }}>{{ page }}</a></li>
{% elif page == None %}
<li class="disabled"><a href={{ url_for(fname,page=1) }}>...</a></li>
{% else %}
<li><a href={{ url_for(fname,page=page) }}>{{ page }}</a></li>
{% endif %}
{% endfor %}
{% if todos.has_next %}
<li><a href="{{ url_for(fname,page=todos.next_num) }}">下一頁</a></li>
{% else %}
<li class="disabled"><a href="#">下一頁</a></li>
{% endif %}
</ul>
{% endmacro %}