请教Flask使用url_for创建分页链接的问题?

flasky学习过程中,有关分页的那部分使用url_for生成url的问题

假设查看的用户是haha

1.在用户头像创建的url

<a href="{{ url_for('.user', username = follow.user.username) }}">

生成的url是 http://xxx/user/haha

2.在下边分页创建导航栏的url

# 路由
@main.route('/followed_by/<username>')
def followed_by(username):
    user = User.query.filter_by(username=username).first()
    if user is None:
        flash('Invalid user.')
        return redirect(url_for('.index'))
    page = request.args.get('page', 1, type=int)
    pagination = user.followed.paginate(
        page=page, per_page=current_app.config['FLASKY_FOLLOWERS_PER_PAGE'],
        error_out=False)
    follows = [{'user': item.followed, 'timestamp': item.timestamp}
               for item in pagination.items]
    return render_template('followers.html', user=user, title="Followed by",
                           endpoint='.followed_by', pagination=pagination,
                           follows=follows)

定义的宏

{% macro pagination_widget(pagination, endpoint) %}
...
 <a href="{{ url_for(endpoint, page = p, **kwargs) }}">{{ p }}</a>

模板调用宏

    {{ macros.pagination_widget(pagination, endpoint, username = user.username) }}

为什么生成的url是 http://xxx/followers_by/haha?page=1
而不是是http://xxx/followers_by/?page=1&username=haha

希望老师讲解。

阅读 481
avatarAI BotBETA

当你使用 Flask 的 url_for 函数生成 URL 时,它会基于你提供的端点(endpoint)和参数来构造 URL。在你的例子中,端点是 .followed_by,这个端点对应于你的路由 @main.route('/followed_by/<username>')

当你在模板中使用 url_for 生成分页链接时,你传递了 endpointpage 参数。然而,你没有传递 username 参数,这是导致 URL 不正确的原因。

为了解决这个问题,你需要在 pagination_widget 宏中传递 username 参数,并确保在 url_for 调用中正确地使用它。你可以通过在宏中接收 kwargs(关键字参数)来实现这一点,并在模板中调用宏时传递所有需要的参数。

下面是修改后的模板和宏代码示例:

<!-- 模板中调用 pagination_widget 宏 -->
{% macro pagination_widget(pagination, endpoint, **kwargs) %}
  ...
  <a href="{{ url_for(endpoint, page=p, **kwargs) }}">{{ p }}</a>
  ...
{% endmacro %}

<!-- 在模板中使用 pagination_widget 宏 -->
{{ pagination_widget(pagination, '.followed_by', username=user.username) }}

在这个修改后的代码中,pagination_widget 宏现在接收一个额外的 **kwargs 参数,用于传递其他关键字参数(如 username)。在模板中调用 pagination_widget 时,你需要传递 username=user.username 作为关键字参数。这样,url_for 函数将能够正确地构造包含 username 的 URL。

现在,生成的 URL 应该类似于 http://xxx/followed_by/haha?page=1,其中 haha 是用户名。这样,你的分页链接就会正确地包含用户名参数。

1 个回答
新手上路,请多包涵

发现了原因
@main.route('/followed_by/<username>')
应为url_for提交的路由要求匹配<username>
当使用url_for(endpoint, page = p, username='haha')的时候
路由会自动匹配username='haha',所以生成的url变成了/followed_by/haha?page=1
路由会自动把匹配的参数提到?前边

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