《flask web 开发》中管理员资料编辑链接报错?

新手上路,请多包涵

问题描述

werkzeug.routing.BuildError: Could not build url for endpoint 'main.edit_profile_admin' with values ['id']. Did you mean 'main.edit_profile' instead?

问题出现的环境背景及自己尝试过哪些方法

在user.html里面编辑adminstrator用户edit_profile的链接,模板中传入了参数id,视图函数里也有id参数,但报错信息好像说的是不能用值id作为端点构建url?网上搜索了类似的问题没有符合我的情况的

相关代码

app/main/view.py(部分)

@main.route('/edit-profile/<int:id>', methods = ['GET', 'POST'])
@login_required
@admin_required
def edit_profile_admin(id):
    user = User.query.get_or_404(id)
    form = EditProfileAdminForm(user=user)
    if form.validate_on_submit():
        user.email = form.email.data
        user.username = form.username.data
        user.confirmed = form.confirmed.data
        user.role = Role.query.get(form.role.data)
        user.name = form.name.data
        user.location = form.location.data
        user.about_me = form.about_me.data
        db.session.add(user)
        flash('The profile has been updated')
        return redirect(url_for('.user', username=user.username))
    form.email.data = user.email
    form.username.data = user.username
    form.confirmed.data = user.confirmed
    form.role.data = user.role_id
    form.name.data = user.name
    form.location.data = user.name
    form.about_me.data = user.about_me
    return render_template('edit_profile.html', form=form, user=user)

app/main/form.py

from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField, TextAreaField, BooleanField, SelectField, ValidationError
from wtforms.validators import DataRequired, Length, Email, Regexp
from ..models import Role, User

class NameForm(FlaskForm):
    name = StringField('What is your name?', validators=[DataRequired()])
    submit = SubmitField('Submit')

class EditProfileForm(FlaskForm):
    name = StringField('Real name', validators=[Length(0, 64)])
    location = StringField('Location', validators=[Length(0, 64)])
    about_me = TextAreaField('About me')
    submit = SubmitField('Submit')

class EditProfileAdminForm(FlaskForm):
    email = StringField('Email', validators=[DataRequired(),
                                             Length(1, 64), Email()])
    username = StringField('Username', validators=[
        DataRequired(), Length(1, 64), Regexp('^[A-Za-z][A-Za-z0-9_.]*$', 0,
                                              'Usernames must have only '
                                              'letters, numbers, dots '
                                              'or underscores')
    ])
    confirmed = BooleanField('Confirmed')
    role = SelectField('Role', coerce=int)
    name = SelectField('Real name', validators=['Length(0,64)'])
    location = StringField('Location', validators=[Length(0, 64)])
    about_me = TextAreaField('About me')
    submit = SubmitField('Submit')

    def __init__(self, user, *args, **kwargs):
        super(EditProfileAdminForm, self).__init__(*args, **kwargs)
        self.role.choices = [(role.id, role.name) for role in Role.query.order_by(Role.name).all()]
        self.user = user

    def validate_email(self, field):
        if field.data != self.user.email and \
            User.query.filter_by(email=field.data).first():
            raise ValidationError('Email already registered.')

    def validate_username(self, field):
        if field.data != self.user.username and \
            User.query.filter_by(email=field.data).first():
            raise ValidationError('Username already in use.')

app/templates/user.html

{% extends "base.html" %}

{% block title %}Flasky - {{ user.username }}{% endblock %}

{% block page_content %}
<div class="page-header">
    <h1>{{ user.username }}</h1>
    {% if user.name or user.location %}
    <p>
        {% if user.name %}{{ user.name }}{% endif %}
        {% if user.location %}
            from <a href="http://maps.google.com/?q={{ user.location }}">{{ user.location }}</a>
        {% endif %}
    </p>
    {% endif %}
    {% if current_user.is_administrator() %}
    <p><a href="mailto:{{ user.email }}">{{ user.email }}</a></p>
    {% endif %}
    {% if user.about_me %}<p>{{ user.about_me }}</p>{% endif %}
    <p>Member since {{ moment(user.member_since).format('L') }}. Last seen {{ moment(user.last_seen).fromNow() }}.</p>
    <p>
        {% if user == current_user %}
        <a class="btn btn-default" href="{{ url_for('.edit_profile') }}">Edit Profile</a>
        {% endif %}
        {% if current_user.is_administrator() %}
        <a class="btn btn-danger" href="{{ url_for('.edit_profile_admin', id=user.id) }}">Edit Profile [Admin]</a>
        {% endif %}
    </p>
</div>
{% endblock %}

完整的traceback
Traceback (most recent call last)

File "/home/zhang/PycharmProjects/flasky2/venv/lib/python3.5/site-packages/flask/app.py", line 2309, in __call__

return self.wsgi_app(environ, start_response)

File "/home/zhang/PycharmProjects/flasky2/venv/lib/python3.5/site-packages/flask/app.py", line 2295, in wsgi_app

response = self.handle_exception(e)

File "/home/zhang/PycharmProjects/flasky2/venv/lib/python3.5/site-packages/flask/app.py", line 1741, in handle_exception

reraise(exc_type, exc_value, tb)

File "/home/zhang/PycharmProjects/flasky2/venv/lib/python3.5/site-packages/flask/_compat.py", line 35, in reraise

raise value

File "/home/zhang/PycharmProjects/flasky2/venv/lib/python3.5/site-packages/flask/app.py", line 2292, in wsgi_app

response = self.full_dispatch_request()

File "/home/zhang/PycharmProjects/flasky2/venv/lib/python3.5/site-packages/flask/app.py", line 1815, in full_dispatch_request

rv = self.handle_user_exception(e)

File "/home/zhang/PycharmProjects/flasky2/venv/lib/python3.5/site-packages/flask/app.py", line 1718, in handle_user_exception

reraise(exc_type, exc_value, tb)

File "/home/zhang/PycharmProjects/flasky2/venv/lib/python3.5/site-packages/flask/_compat.py", line 35, in reraise

raise value

File "/home/zhang/PycharmProjects/flasky2/venv/lib/python3.5/site-packages/flask/app.py", line 1813, in full_dispatch_request

rv = self.dispatch_request()

File "/home/zhang/PycharmProjects/flasky2/venv/lib/python3.5/site-packages/flask/app.py", line 1799, in dispatch_request

return self.view_functions[rule.endpoint](**req.view_args)

File "/home/zhang/PycharmProjects/flasky2/app/main/views.py", line 37, in user

return render_template('user.html', user=user)

File "/home/zhang/PycharmProjects/flasky2/venv/lib/python3.5/site-packages/flask/templating.py", line 135, in render_template

context, ctx.app)

File "/home/zhang/PycharmProjects/flasky2/venv/lib/python3.5/site-packages/flask/templating.py", line 117, in _render

rv = template.render(context)

File "/home/zhang/PycharmProjects/flasky2/venv/lib/python3.5/site-packages/jinja2/environment.py", line 1008, in render

return self.environment.handle_exception(exc_info, True)

File "/home/zhang/PycharmProjects/flasky2/venv/lib/python3.5/site-packages/jinja2/environment.py", line 780, in handle_exception

reraise(exc_type, exc_value, tb)

File "/home/zhang/PycharmProjects/flasky2/venv/lib/python3.5/site-packages/jinja2/_compat.py", line 37, in reraise

raise value.with_traceback(tb)

File "/home/zhang/PycharmProjects/flasky2/app/templates/user.html", line 1, in top-level template code

{% extends "base.html" %}

File "/home/zhang/PycharmProjects/flasky2/app/templates/base.html", line 1, in top-level template code

{% extends "bootstrap/base.html" %}

File "/home/zhang/PycharmProjects/flasky2/venv/lib/python3.5/site-packages/flask_bootstrap/templates/bootstrap/base.html", line 1, in top-level template code

{% block doc -%}

File "/home/zhang/PycharmProjects/flasky2/venv/lib/python3.5/site-packages/flask_bootstrap/templates/bootstrap/base.html", line 4, in block "doc"

{%- block html %}

File "/home/zhang/PycharmProjects/flasky2/venv/lib/python3.5/site-packages/flask_bootstrap/templates/bootstrap/base.html", line 20, in block "html"

{% block body -%}

File "/home/zhang/PycharmProjects/flasky2/venv/lib/python3.5/site-packages/flask_bootstrap/templates/bootstrap/base.html", line 23, in block "body"

{% block content -%}

File "/home/zhang/PycharmProjects/flasky2/app/templates/base.html", line 51, in block "content"

{% block page_content %}{% endblock %}

File "/home/zhang/PycharmProjects/flasky2/app/templates/user.html", line 26, in block "page_content"

<a class="btn btn-danger" href="{{ url_for('.edit_profile_admin', id=current_user.id) }}">Edit Profile [Admin]</a>

File "/home/zhang/PycharmProjects/flasky2/venv/lib/python3.5/site-packages/flask/helpers.py", line 356, in url_for

return appctx.app.handle_url_build_error(error, endpoint, values)

File "/home/zhang/PycharmProjects/flasky2/venv/lib/python3.5/site-packages/flask/app.py", line 2061, in handle_url_build_error

reraise(exc_type, exc_value, tb)

File "/home/zhang/PycharmProjects/flasky2/venv/lib/python3.5/site-packages/flask/_compat.py", line 35, in reraise

raise value

File "/home/zhang/PycharmProjects/flasky2/venv/lib/python3.5/site-packages/flask/helpers.py", line 345, in url_for

force_external=external)

File "/home/zhang/PycharmProjects/flasky2/venv/lib/python3.5/site-packages/werkzeug/routing.py", line 1776, in build

raise BuildError(endpoint, values, method, self)

werkzeug.routing.BuildError: Could not build url for endpoint 'main.edit_profile_admin' with values ['id']. Did you mean 'main.edit_profile' instead?

       




阅读 2.7k
3 个回答

修改app/templates/user.html的部分内容如下:

        {% if current_user.is_administrator() %}
        <a class="btn btn-danger" href="{{ url_for('.edit_profile', id=user.id) }}">Edit Profile [Admin]</a>
        {% endif %}
{% endblock %}

url_for('.edit_profile', id=user.id) 应该的 endpoint 应该使用函数的名称。

新手上路,请多包涵

解决了吗? 我也遇到这个问题,找不到头绪

新手上路,请多包涵

你使用了自定义的@admin_required装饰器
可能是你的decorators.py写错了,检查一下。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题