1. 程式人生 > >flask -- 任務管理專案

flask -- 任務管理專案

資料庫程式碼

通過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 %}

顯示效果

在這裡插入圖片描述

在這裡插入圖片描述

在這裡插入圖片描述