基于Flask与Mariadb实现任务清单管理

目标:

  1. 实现任务的添加,修改状态与删除
  2. 任务只能在登陆状态下实现上面的功能
  3. 添加任务时:显示发布任务的时间与部门等

将此次目标新建一个Flask项目,项目名为(Todo)
基于Flask与Mariadb实现任务清单管理_第1张图片
Todo项目包含上图所示文件(migrations:数据库扩展;static:静态文件;templates:html文件;forms:表单处理;manager:数据库扩展;models:连接数据库;run:主函数;views:主函数的路径与视图函数)

主函数(run.py)

from models import app
from views import *

if __name__ == '__main__':
    app.run()

主函数的路径与视图函数(views.py)

from flask import render_template, redirect, url_for, request, session

from models import app, Todo, db, Department, User, Userlog

from forms import LoginForm,RegisterForm

import  functools


def is_login(f):
    """判断用户是否登陆的装饰器"""
    @functools.wraps(f)
    def wrapper(*args, **kwargs):
        if 'user' not in session:
            return  redirect('/login/')
        return  f(*args, **kwargs)
    return  wrapper


@app.route('/')
def index():
    todos=Todo.query.all()
    parts=Department.query.all()
    return render_template('index.html',
                           todos=todos,
                           parts=parts
                           )

@app.route('/login/',methods=['GET','POST'])
def login():
    form = LoginForm()
    if form.validate_on_submit():
        user = form.data['user']
        passwd = form.data['passwd']

        u = User.query.filter_by(name=user).first()
        if u.pwd==passwd:
            session['user']=u.name
            session['user_id']=u.id
            # session['user_id']=u.id
            userlog=Userlog(
            user_id=u.id
            )
            db.session.add(userlog)
            db.session.commit()
            return redirect(url_for('todo_list'))
        else:
            return render_template('login.html', form=form, message='用户名或密码错误')
    return render_template('login.html', form=form)

@app.route('/register/',methods=['GET','POST'])
def register():
    form=RegisterForm()
    if form.validate_on_submit():
        user=form.data['user']
        passwd=form.data['passwd']
        u = User(name=user, pwd=passwd, department_id=1)
        db.session.add(u)
        db.session.commit()
        return redirect(url_for('login'))
    return render_template('register.html',form=form)

@app.route('/logout/')
def logout():
    return redirect(url_for('index'))

# 任务的增删改查

@app.route('/todo/add/',methods=['POST'])
@is_login
def todo_add():
    name=request.form['todo_name']
    part=request.form['part']
    todo=Todo(name=name,department_id=part,user_id=1)
    db.session.add(todo)
    db.session.commit()
    return redirect(url_for('todo_list'))

@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()
    return redirect(url_for('todo_list'))


@app.route('/list/')
def todo_list():
    #从数据库中查询
    todos=Todo.query.all()
    parts=Department.query.all()
    return render_template('list.html',
                           todos=todos,
                           parts=parts
                           )
# 修改任务状态

@app.route('/todo/undo//')
@is_login
def undo(id):
    todo=Todo.query.filter_by(id=id).first()
    todo.status=False
    db.session.commit()
    return redirect(url_for('todo_list'))

@app.route('/todo/done//')
@is_login
def done(id):
    todo = Todo.query.filter_by(id=id).first()
    todo.status = True
    db.session.commit()
    return redirect(url_for('todo_list'))

数据库的连接,数据表与数据的初步建立(models.py)

from datetime import datetime
from flask import Flask

from flask_sqlalchemy import SQLAlchemy
import os
from flask_bootstrap import Bootstrap

app=Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI']="mysql+pymysql://root:redhat@localhost/Todo"
app.config['SECRET_KEY'] =  os.urandom(24)
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True

db=SQLAlchemy(app)
bootstrap=Bootstrap(app)

class Todo(db.Model):
    id=db.Column(db.INTEGER,autoincrement=True,primary_key=True)
    name = db.Column(db.String(200),nullable=False)
    add_time = db.Column(db.DateTime, default=datetime.now())
    status=db.Column(db.BOOLEAN,default=False)
    department_id=db.Column(db.INTEGER, db.ForeignKey('department.id'))
    user_id=db.Column(db.INTEGER, db.ForeignKey('user.id'))

    def __repr__(self):
        return ''%(self.name)

class Department(db.Model):
    id = db.Column(db.INTEGER, autoincrement=True, primary_key=True)
    name = db.Column(db.String(50), unique=True, nullable=False)
    users=db.relationship('User',backref='department')
    todos=db.relationship('Todo',backref='department')

    def __repr__(self):
        return ''%(self.name)

class User(db.Model):
    id = db.Column(db.INTEGER, autoincrement=True, primary_key=True)
    name = db.Column(db.String(50), unique=True, nullable=False)
    pwd = db.Column(db.String(100))
    email = db.Column(db.String(30), unique=True)
    info = db.Column(db.TEXT)
    add_time = db.Column(db.DateTime, default=datetime.now())
    department_id = db.Column(db.INTEGER, db.ForeignKey('department.id'))
    todos = db.relationship('Todo', backref='user')
    userlogs = db.relationship('Userlog', backref='user')

    def __repr__(self):
        return ''%(self.name)

class Userlog(db.Model):
    id = db.Column(db.INTEGER, autoincrement=True, primary_key=True)
    add_time = db.Column(db.DateTime, default=datetime.now())
    # ip=db.Column(db.String(200),nullable=False)
    # area=db.Column(db.String(200))
    user_id = db.Column(db.INTEGER, db.ForeignKey('user.id'))

    def __repr__(self):
        return ''%(self.name)

if __name__ == '__main__':
    db.drop_all()
    db.create_all()

    parts=['开发部','人事部','运维部']
    partObj=[Department(name=part) for part in parts]
    db.session.add_all(partObj)
    db.session.commit()

    u1=User(name='westos',pwd='westos',department_id=1)
    db.session.add(u1)
    db.session.commit()

表单处理,接收输入框组中的数据(forms.py)

from flask_wtf import FlaskForm

from wtforms import StringField,PasswordField,SubmitField

from wtforms.validators import Length,Email,EqualTo,Regexp



class LoginForm(FlaskForm):
    user=StringField(
        label='用户名',
    )
    passwd=PasswordField(
        label='密码',
    )
    submit=SubmitField(
        label='登陆',
    )

class RegisterForm(FlaskForm):
    user = StringField(
        label="用户名/手机/邮箱",
        validators=[
            Length(5, 12),
        ]
    )
    email = StringField(
        label="邮箱",
        validators=[
            Email("邮箱格式不正确!")
        ]
    )
    phone = StringField(
        label="电话",
        validators=[
            Regexp(r'1\d{10}', message="手机格式不正确!")
        ]
    )
    passwd = PasswordField(
        label="密码",
        validators=[
            Length(6)
        ]
    )

    repasswd =  PasswordField(
        label="确认密码",
        validators=[
          EqualTo('passwd', "两次密码不一致!")
        ]

    )

    submit = SubmitField(
        label="注册"

    )

数据库的扩展,数据库扩建时使用,还有一些自定义的函数(manager.py)

from flask_script import Manager
from flask_migrate import Migrate,MigrateCommand

from models import app, db, User, Department

manager=Manager(app)
migrete=Migrate(app,db)

manager.add_command('db',MigrateCommand)

@manager.command
def show_depart():
    """显示所有部门"""
    departs=Department.query.all()
    print(departs)

@manager.option('-n','--name',help='添加部门')
def add_depart(name):
    """添加部门"""
    try:
        depart1=Department(name=name)
        db.session.add(depart1)
        db.session.commit()
    except:
        print('添加部门失败')
    else:
        print('添加部门%s成功'%(name))

if __name__ == '__main__':
    manager.run()

templates 中的 html 页面:

base.html

{#自己编写一个基类模板#}
{% extends "bootstrap/base.html" %}

{% block styles %}
    {{ super() }}
    
{% endblock %}


{% block navbar %}
    
{% endblock %}



{% block content %}
    {#定义属于自己的block#}
    {% block  newcontent %}

    {% endblock %}


{% endblock %}

index.html

{% extends 'base.html' %}

{% block title %}
主页
{% endblock %}

{% block newcontent %}

请先登录后,再添加任务

{% for todo in todos %} {# #} {% endfor %}
任务内容 创建时间 状态 所属部门 操作
{{ todo.name }} {{ todo.add_time }} {% if todo.status %} 已完成 {% else %} 未完成 {% endif %} {{ todo.department.name }} 删除
{% endblock %}

login.html

{% extends 'base.html' %}
{% import 'bootstrap/wtf.html' as wtf %}

{% block title %}
登陆
{% endblock %}

{% block newcontent %}

登录 没有账号?注册

{{ wtf.quick_form(form) }} {% if message %}

{{message}}

{% endif %}
{% endblock %}

register.html

{% extends "base.html" %}
{%  import "bootstrap/wtf.html" as wtf %}

{% block title %}
注册
{% endblock %}


{% block newcontent %}

注册 没有账号?注册

{{ wtf.quick_form(form) }}
{% endblock %}

list.html

{% extends 'base.html' %}
{% block title %}用户显示{% endblock %}
{% block logout %}   登出{% endblock %}
{% block newcontent %}
    
{# 添加框 #}
{# 选择框 #}
{# 添加的按钮 #}

添加任务

{% for todo in todos %} {# #} {% endfor %}
任务内容 创建时间 状态 所属部门 操作
{{ todo.name }} {{ todo.add_time }} {% if todo.status %} 已完成 {% else %} 未完成 {% endif %} {{ todo.department.name }} 删除
{% endblock %}

执行结果:

首先进入清单后
基于Flask与Mariadb实现任务清单管理_第2张图片
此页面下不能添加任务、修改任务和删除任务,只有在登陆状态下,才可以进行,如果非要进行的话,会跳转到登陆页面

先进行登陆
基于Flask与Mariadb实现任务清单管理_第3张图片
由于初始数据库中只有(用户名和密码都为 westos )的用户,因此密码错误

登陆成功后基于Flask与Mariadb实现任务清单管理_第4张图片
会跳转到 list 页面,方可执行任务的修改

倘若没有帐号,可以注册一个
基于Flask与Mariadb实现任务清单管理_第5张图片
注册要求,要符合 forms 表单中的要求,注册成功后,就会调转到登陆页面

在 list 可以执行任务的增加
基于Flask与Mariadb实现任务清单管理_第6张图片
有新的任务添加成功,默认的状态是未完成

可以进行任务状态的修改
基于Flask与Mariadb实现任务清单管理_第7张图片
完成看篮球比赛的任务时,可将未完成,改为已完成的状态

可以进行任务的删除
基于Flask与Mariadb实现任务清单管理_第8张图片
将已完成的两个任务删除掉

主要运用到的就是 上一篇博客说到的 flask、flask_wtf、flask_bootstrap、flask_sqlalchemy、flask_migrate 和 falsk_script 这6个第三方库组成了整个的 Flask 框架

你可能感兴趣的:(基于Flask与Mariadb实现任务清单管理)