每个烧瓶视图功能有多个路径是不好的做法吗?

Cho*_*key 1 python flask flask-sqlalchemy flask-wtforms

所以基本上我有render_template基于if语句的多个返回,并且它们返回我的jinja2模板响应的不同变量.我相信我可以将这些路径分解为自己的功能(同样我可以将我的模板分解为多个模板(例如edit.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)
Run Code Online (Sandbox Code Playgroud)

obm*_*arg 7

这个问题的答案可能与个人品味有关,但我个人不会做这样的事情.我的主要原因只是让事情变得简单 - 你在该函数中有三个嵌套的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)
Run Code Online (Sandbox Code Playgroud)

编辑:澄清 - 我并不是说每个烧瓶路线有多个网址是错误的.在这种情况下,我认为让一个函数做三个完全不同的事情是个坏主意.我确实使用了每个视图的多个路由的其他用例.例如,在我自己的代码中,我经常有这样的视图:

@migrations_tasks.route('/external_applications', methods=['GET'])
@migrations_tasks.route('/external_applications/<cursor>', methods=['POST'])
def migrate_external_applications(cursor=None, subdomain=None):
    ... do stuff
Run Code Online (Sandbox Code Playgroud)

备用路由将光标接受到数据库查询以进行分页.代码流基本相同,只是第一页和后续页面有不同的URL.