使用多个路由的flask视图函数是否存在不良做法?

2024-09-25 08:35:41 发布

您现在位置:Python中文网/ 问答频道 /正文

因此,基本上我有多个基于if语句的render_template返回,它们返回我的jinja2模板响应的不同变量。我相信我可以将这些路径分解成它们自己的函数(同样,我也可以将我的模板分解成多个模板(例如编辑.html模板,而不是模板中的{% if editform %}),但我喜欢为任何给定页面提供单一视图函数和模板的想法。在

在我花更多的时间创建视图的其余函数之前,我想确保我正在做的事情不会在以后影响我。在

下面的代码,谢谢!在

@app.route('/admin/users/', defaults={'id': None}, methods = ['GET'])
@app.route('/admin/users/<id>', methods = ['GET'])
@app.route('/admin/users/edit/<id>', methods = ['GET', 'POST'])
@login_required
def users(id):
    if not current_user.role == ROLE_ADMIN:
        flash('You do not have access to view this page.')
        return redirect(url_for('index'))

    if id:
        user = User.query.filter_by(id = id).first()

        if 'edit' in request.path:
            editform = UserForm()

            if editform.validate_on_submit():
                user.username = editform.username.data
                user.email = editform.email.data
                user.role = editform.role.data

                db.session.add(user)
                db.session.commit()

                return redirect('/admin/users/' + str(user.id))

            editform.username.data = user.username
            editform.email.data = user.email
            editform.role.data = user.role

            return render_template("users.html",
                title = "Edit User",
                user = user,
                editform = editform)

        return render_template("users.html",
            title = "User",
            user = user)

    users = User.query.all()

    return render_template("users.html",
        title = 'Users',
        users = users)

Tags: 模板iddatareturnifadminhtmlusername
2条回答

这个问题的答案可能有点取决于个人品味,但就我个人而言,我会避免做这样的事情。我的主要原因是保持简单-在函数中有三个嵌套的if语句,它们基本上做的工作与如果你要拆分视图的话,这些语句所做的工作是完全相同的。在

诚然,目前这并不是一个大问题,但是如果你在任何一条路径上添加更多的逻辑,那么它可能会导致一个令人惊讶的复杂函数。这可能会导致一些细微的错误,或者只是很难从一眼就知道到底发生了什么。在

但是,如果你把事情分开,每一条路线到底在做什么,应该一眼就能看出来。甚至不需要更多的代码,因为您可以去掉所有if语句:

@app.route('/admin/users/', methods = ['GET'])
def get_all_users():
    users = User.query.all()

    return render_template("users.html",
        title = 'Users',
        users = users)

@app.route('/admin/users/<id>', methods = ['GET'])
def get_single_user(id):
    user = User.query.filter_by(id = id).first()

    return render_template("users.html",
        title = "User",
        user = user)

@app.route('/admin/users/edit/<id>', methods = ['GET', 'POST'])
def edit_user(id):
    editform = UserForm()

    if editform.validate_on_submit():
        user.username = editform.username.data
        user.email = editform.email.data
        user.role = editform.role.data

        db.session.add(user)
        db.session.commit()

        return redirect('/admin/users/' + str(user.id))

    editform.username.data = user.username
    editform.email.data = user.email
    editform.role.data = user.role

    return render_template("users.html",
        title = "Edit User",
        user = user,
        editform = editform)

编辑:澄清一下-我并不是说每个flask路径有多个url是错误的。在这种情况下,我认为让一个函数执行三个完全不同的任务是不好的。我确实利用了每个视图的多条路线的其他用例。例如,在我自己的代码中,我经常有这样的视图:

^{pr2}$

其中替代路由接受一个游标到数据库查询中进行分页。代码的流程基本相同,只是第一个页面和后续页面有不同的URL。在

没有硬性规定,但我建议按照Separation of concerns原则,拆分成多个函数更模块化。在

我甚至会更进一步,使用MethodView,其中每个路由都有一个类,其中get、post、post等从base重写。在

当你的函数很小的时候它看起来还可以,但是当它增长的时候,一些模块化是有帮助的!在

相关问题 更多 >