最新消息: USBMI致力于为网友们分享Windows、安卓、IOS等主流手机系统相关的资讯以及评测、同时提供相关教程、应用、软件下载等服务。

flask项目流程(三)

互联网 admin 1浏览 0评论

flask项目流程(三)

flask项目流程(三)

  • 任务模块的编写
url_for传递参数方式
{{ url_for('task.status',code=1) }}

报错:

RuntimeError: No application found. Either work inside a view function or push an application context. See htt
p://flask-sqlalchemy.pocoo.org/contexts/.

尽量不要再表单中执行数据库模型操作,将该操作转移至视图函数中

  • 添加任务表单的制作
# forms.py
class AddTaskForm(FlaskForm):content = TextAreaField(label='内容', validators=[DataRequired()])add_time = DateTimeField('添加日期', default=datetime.utcnow)category = SelectField(label='类别', coerce=int, choices='', validators=[DataRequired()])submit = SubmitField('添加')note:
# coerce=int html中的表单都是字符串类型,coerce使得在进行提交验证的时候转换为int类型
  • choices的添加放在视图函数部分
# views.py
def add():form = AddTaskForm()categories = Category.query.filter_by(user_id=current_user.id)if categories:form.category.choices = [(category.id, category.name) for category in categories]else:form.category.choices = [(-1, '请先创建分类')]#…………return render_template('task/add.html', form=form)
  • 分页展示的视图编写

  • flask-sqlchemy的使用

文档地址:.x/

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HbCRJSC4-1590067379381)(C:\Users\小木人\AppData\Roaming\Typora\typora-user-images\image-20200521100317859.png)]

  • list视图函数
# views.py
@task.route('/list')
def list():# 从url传递的参数中获取数据page,html传过来的数据为字符串类型,需要转化为intpage = int(request.args.get('page'))# paginat返回的是一个分页对象tasksPagination = Task.query.filter_by(user_id=current_user.id).paginate(page=page, per_page=3)# 获取分页中的元素 the items for the current pagetasks = tasksPagination.itemsreturn render_template('task/list.html', tasksPagination=tasksPagination, tasks=tasks)
  • 前端页面
<table class="table table-bordered"><caption>任务清单</caption><thead><tr><th>任务内容</th><th>任务起始时间</th><th>完成状态</th><th>任务操作</th></tr></thead><tbody>{% for task in tasks %}<tr><td>{{ task.content }}</td><td>{{ task.add_time }}</td><td>{{ task.status }}</td><td><a>编辑</a><a>删除</a></td></tr>{% endfor %}</tbody></table># 查看分页对象有无上一页{% if tasksPagination.has_prev %}<a href="{{ url_for('task.list') }}?page={{ tasksPagination.prev_num }}">上一页</a>{% endif %}# 将分页对象的所有页数用一个列表显示{% for page in tasksPagination.iter_pages() %}<a href="{{ url_for('task.list') }}?page={{ page }}">{{ page }}</a>{% endfor %}{% if tasksPagination.has_next %}<a href="{{ url_for('task.list') }}?page={{ tasksPagination.next_num }}">下一页</a>{% endif %}
  • 任务编辑视图
# forms.py
class EditTaskForm(FlaskForm):content = TextAreaField(label='内容', validators=[DataRequired()])#  coerce=int html中的表单都是字符串类型,coerce使得在进行提交验证的时候转换为int类型category = SelectField(label='类别', coerce=int, choices=[], validators=[DataRequired()])status = RadioField(label='完成状态', coerce=int, choices=[(1, '已完成'), (0, '未完成')])submit = SubmitField('修改')
@task.route('/edit/<task_id>', methods=('GET', 'POST'))
@login_required
def edit(task_id):# 实例化表单对象form = EditTaskForm()categories = Category.query.filter_by(user_id=current_user.id)if categories:form.category.choices = [(category.id, category.name) for category in categories]else:form.category.choices = [(-1, '请先创建分类')]# 查询任务是否存在task = Task.query.filter_by(id=task_id).first()# print(form.validate_on_submit())if form.validate_on_submit():# print('8' * 50)# print(form.data)task.content = form.data['content']task.category_id = form.data['category']task.status = form.data['status']db.session.add(task)db.session.commit()flash('任务修改成功', category='success')return redirect(url_for('task.list'))# print(task)if task:print('*' * 50)# 显示出原先的任务内容form.content.data = task.contentform.status.data = 1 if task.status else 0form.category.data = task.category_idprint(task.category_id)else:flash('该任务不存在', category='error')return redirect(url_for('task.list'))return render_template('task/edit.html', form=form)

踩坑:

  1. form.validate_on_submit() 一直为False

    问题可能是因为表单里没有validators,如果表单里没有写validators的话,相当于提交的表单内容是空,后端的form.validate_on_submit()就会一直是false。

  2. Flask SelectField (Not a vaild choice)

    验证当前选择值是否能在我在后端定义表单时赋的choices值里被找到。找不到就报错Not a vaild choice。上述代码是将放在验证函数前面

    categories = Category.query.filter_by(user_id=current_user.id)if categories:form.category.choices = [(category.id, category.name) for category in categories]else:form.category.choices = [(-1, '请先创建分类')]
  • 查看所有分类
# views.py
@task.route('/categories')
@login_required
def categories():page = int(request.args.get('page', 1))# 获取所有的分类的分页对象categoriesPagination = Category.query.filter_by(user_id=current_user.id).paginate(page=page, per_page=3)categories = categoriesPagination.itemsreturn render_template('task/category.html', categoriesPagination=categoriesPagination,categories=categories)
  • 查看状态
@task.route('/status/<code>')
@login_required
def status(code):# 这里前端穿的code是str类型tasks = []if int(code) == 1:tasks += Task.query.filter_by(user_id=current_user.id, status=True)else:tasks += Task.query.filter_by(user_id=current_user.id, status=False)print(tasks)return render_template('task/status.html', tasks=tasks)
  • 状态更改视图函数
@task.route('/change_status/<task_id>')
@login_required
def change_status(task_id):task = Task.query.filter_by(user_id=current_user.id, id=task_id).first()if task.status:task.status = Falseelse:task.status = Truedb.session.add(task)db.session.commit()flash('状态修改成功', category='success')return redirect(url_for('task.list'))

报错:

AttributeError: ‘BaseQuery’ object has no attribute ‘status’

task = Task.query.filter_by(user_id=current_user.id, id=task_id)
上述语句查询出来的是一个列表,需要使用first()拿出第一条记录
  • 分类详情的视图函数
# views.py
# 查看该分类下的所有任务
@task.route('/category_detail/<category_id>')
@login_required
def category_detail(category_id):tasks = Task.query.filter_by(category_id=category_id, user_id=current_user.id)return render_template('task/category_detail.html', tasks=tasks)

route(’/category_detail/<category_id>’)
@login_required
def category_detail(category_id):
tasks = Task.query.filter_by(category_id=category_id, user_id=current_user.id)
return render_template(‘task/category_detail.html’, tasks=tasks)


flask项目流程(三)

flask项目流程(三)

  • 任务模块的编写
url_for传递参数方式
{{ url_for('task.status',code=1) }}

报错:

RuntimeError: No application found. Either work inside a view function or push an application context. See htt
p://flask-sqlalchemy.pocoo.org/contexts/.

尽量不要再表单中执行数据库模型操作,将该操作转移至视图函数中

  • 添加任务表单的制作
# forms.py
class AddTaskForm(FlaskForm):content = TextAreaField(label='内容', validators=[DataRequired()])add_time = DateTimeField('添加日期', default=datetime.utcnow)category = SelectField(label='类别', coerce=int, choices='', validators=[DataRequired()])submit = SubmitField('添加')note:
# coerce=int html中的表单都是字符串类型,coerce使得在进行提交验证的时候转换为int类型
  • choices的添加放在视图函数部分
# views.py
def add():form = AddTaskForm()categories = Category.query.filter_by(user_id=current_user.id)if categories:form.category.choices = [(category.id, category.name) for category in categories]else:form.category.choices = [(-1, '请先创建分类')]#…………return render_template('task/add.html', form=form)
  • 分页展示的视图编写

  • flask-sqlchemy的使用

文档地址:.x/

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HbCRJSC4-1590067379381)(C:\Users\小木人\AppData\Roaming\Typora\typora-user-images\image-20200521100317859.png)]

  • list视图函数
# views.py
@task.route('/list')
def list():# 从url传递的参数中获取数据page,html传过来的数据为字符串类型,需要转化为intpage = int(request.args.get('page'))# paginat返回的是一个分页对象tasksPagination = Task.query.filter_by(user_id=current_user.id).paginate(page=page, per_page=3)# 获取分页中的元素 the items for the current pagetasks = tasksPagination.itemsreturn render_template('task/list.html', tasksPagination=tasksPagination, tasks=tasks)
  • 前端页面
<table class="table table-bordered"><caption>任务清单</caption><thead><tr><th>任务内容</th><th>任务起始时间</th><th>完成状态</th><th>任务操作</th></tr></thead><tbody>{% for task in tasks %}<tr><td>{{ task.content }}</td><td>{{ task.add_time }}</td><td>{{ task.status }}</td><td><a>编辑</a><a>删除</a></td></tr>{% endfor %}</tbody></table># 查看分页对象有无上一页{% if tasksPagination.has_prev %}<a href="{{ url_for('task.list') }}?page={{ tasksPagination.prev_num }}">上一页</a>{% endif %}# 将分页对象的所有页数用一个列表显示{% for page in tasksPagination.iter_pages() %}<a href="{{ url_for('task.list') }}?page={{ page }}">{{ page }}</a>{% endfor %}{% if tasksPagination.has_next %}<a href="{{ url_for('task.list') }}?page={{ tasksPagination.next_num }}">下一页</a>{% endif %}
  • 任务编辑视图
# forms.py
class EditTaskForm(FlaskForm):content = TextAreaField(label='内容', validators=[DataRequired()])#  coerce=int html中的表单都是字符串类型,coerce使得在进行提交验证的时候转换为int类型category = SelectField(label='类别', coerce=int, choices=[], validators=[DataRequired()])status = RadioField(label='完成状态', coerce=int, choices=[(1, '已完成'), (0, '未完成')])submit = SubmitField('修改')
@task.route('/edit/<task_id>', methods=('GET', 'POST'))
@login_required
def edit(task_id):# 实例化表单对象form = EditTaskForm()categories = Category.query.filter_by(user_id=current_user.id)if categories:form.category.choices = [(category.id, category.name) for category in categories]else:form.category.choices = [(-1, '请先创建分类')]# 查询任务是否存在task = Task.query.filter_by(id=task_id).first()# print(form.validate_on_submit())if form.validate_on_submit():# print('8' * 50)# print(form.data)task.content = form.data['content']task.category_id = form.data['category']task.status = form.data['status']db.session.add(task)db.session.commit()flash('任务修改成功', category='success')return redirect(url_for('task.list'))# print(task)if task:print('*' * 50)# 显示出原先的任务内容form.content.data = task.contentform.status.data = 1 if task.status else 0form.category.data = task.category_idprint(task.category_id)else:flash('该任务不存在', category='error')return redirect(url_for('task.list'))return render_template('task/edit.html', form=form)

踩坑:

  1. form.validate_on_submit() 一直为False

    问题可能是因为表单里没有validators,如果表单里没有写validators的话,相当于提交的表单内容是空,后端的form.validate_on_submit()就会一直是false。

  2. Flask SelectField (Not a vaild choice)

    验证当前选择值是否能在我在后端定义表单时赋的choices值里被找到。找不到就报错Not a vaild choice。上述代码是将放在验证函数前面

    categories = Category.query.filter_by(user_id=current_user.id)if categories:form.category.choices = [(category.id, category.name) for category in categories]else:form.category.choices = [(-1, '请先创建分类')]
  • 查看所有分类
# views.py
@task.route('/categories')
@login_required
def categories():page = int(request.args.get('page', 1))# 获取所有的分类的分页对象categoriesPagination = Category.query.filter_by(user_id=current_user.id).paginate(page=page, per_page=3)categories = categoriesPagination.itemsreturn render_template('task/category.html', categoriesPagination=categoriesPagination,categories=categories)
  • 查看状态
@task.route('/status/<code>')
@login_required
def status(code):# 这里前端穿的code是str类型tasks = []if int(code) == 1:tasks += Task.query.filter_by(user_id=current_user.id, status=True)else:tasks += Task.query.filter_by(user_id=current_user.id, status=False)print(tasks)return render_template('task/status.html', tasks=tasks)
  • 状态更改视图函数
@task.route('/change_status/<task_id>')
@login_required
def change_status(task_id):task = Task.query.filter_by(user_id=current_user.id, id=task_id).first()if task.status:task.status = Falseelse:task.status = Truedb.session.add(task)db.session.commit()flash('状态修改成功', category='success')return redirect(url_for('task.list'))

报错:

AttributeError: ‘BaseQuery’ object has no attribute ‘status’

task = Task.query.filter_by(user_id=current_user.id, id=task_id)
上述语句查询出来的是一个列表,需要使用first()拿出第一条记录
  • 分类详情的视图函数
# views.py
# 查看该分类下的所有任务
@task.route('/category_detail/<category_id>')
@login_required
def category_detail(category_id):tasks = Task.query.filter_by(category_id=category_id, user_id=current_user.id)return render_template('task/category_detail.html', tasks=tasks)

route(’/category_detail/<category_id>’)
@login_required
def category_detail(category_id):
tasks = Task.query.filter_by(category_id=category_id, user_id=current_user.id)
return render_template(‘task/category_detail.html’, tasks=tasks)


与本文相关的文章

发布评论

评论列表 (0)

  1. 暂无评论