12.2 在资料页中显示关注者

一. 修改|-app/templates/user.html

    我们想在用户资料页面增加几个栏目如下:

       

    对应的功能举例说明如下:

        如果已登录的用户A(有关注权限的话)访问别的用户B的页面:

            如果A未关注B, 显示一个Follow按钮, 点击关注B, 如果A已经关注B, 显示一个Unfollow按钮, 点击取消关注B;

            Followers列出B的关注者(粉丝)的数量,点击显示B的关注者的列表;

            Followed列出B的被关注者(偶像)的数量, 点击显示B的被关注者的列表;

            如果B关注了A, 后面显示一个Followes you标签。

修改代码如下:

<p>

    {% if current_user.can(Permission.Follow) and current_user != user %}

        {% if not current_user.is_following(user) %}

            <a href="{{ url_for('main.follow', username=user.username) }}" class="btn btn-primary">Follow</a>

        {% else %}

            <a href="{{ url_for('main.unfollow', username=user.username) }}" class="btn btn-default">Unfollow</a>

        {% endif %}

    {% endif %}

    <a href="{{ url_for('main.followers', username=user.username) }}">Followers: <span class="badge">{{ user.followers.count() }}</span></a>

    <a href="{{ url_for('main.followed_by', username=user.username) }}">Followed: <span class="badge">{{ user.followed.count() }}</span></a>

         {% if current_user.is_authenticated and current_user != user and user.is_following(current_user) %}

             <span class="label label-default">Follows you</span>

         {% endif %}

</p>

二. 修改路由函数

1. main.follow

@main.route('/follow/<username>')

@login_required

@permission_required(Permission.FOLLOW)

def follow(username):

    user = User.query.filter_by(username=username).first()

    if not user:

        flash('Invalid user.')

        return redirect(url_for('.index'))

    if current_user.is_following(user):

        flash('You are already following this user.')

        return redirect(url_for('.user', username=username))

    current_user.follow(user)

    flash('You are now following %s' % username)

    return redirect(url_for('.user', username=username))

代码解释:

    之前我们说过, 只有已经登录(1), 具有关注权限(2)的用户A, 访问别的用户(3)B的页面时, 才会根据不同情况关注或者取关B;

    所以我们用if语句, 只有满足以上三个条件时页面才会显示关注和取关按钮, 同样我们用修饰器, 只有满足前两个条件时, 我们才能访问试图函数。 以防止未登录用户直接访问关注链接导致程序出错, 或者无关注权限用户直接访问链接关注用户。

2. main.unfollow

@main.route('/unfollow/<username>')
@login_required
@permission_required(Permission.FOLLOW)
def unfollow(username):
    user = User.query.filter_by(username=username).first()
    if not user:
        flash('Invalid user.')
        return redirect(url_for('.index'))
    if not current_user.is_following(user):
        flash('You never follow this user.')
        return redirect(url_for('.user', username))
    current_user.unfollow(user)
    flash('You have already unfollowed %s.' % username)
    return redirect(url_for('.user', username=username))

3. main.followers

    用户点击Followers链接时, 由本视图函数处理请求,返回参数username对应用户的关注者。

@main.route('/followers/<username>')

def followers(username):

    user = User.query.filter_by(username=username).first()

    if not user:

        flash('Invalid user.')

        return redirect(url_for('.index'))

    page = request.args.get('page', 1, type=int)

    pagination = user.followers.paginate(page, per_page=current_app.config['FLASKY_FOLLOWERS_PER_PAGE'], error_out=False)

    follows = [ {'user': item.follower, 'timestamp': item.timstamp} for item in pagination.items ]

    return render_tempalte('followers.html', user=user, title="Followers of", follows=follows, endpoint=".followers", pagination=pagination)

代码解释:

    pagination:把所有的记录分成per_page页, 返回第page页的页对象, items属性得到第page页的所有记录。 page通过查询参数page获得, 默认为1.

    follows把遍历该页所有记录, 得到所有的关注者和关注时间戳。

4. main.followed_by

    用户点击Followed链接时, 由本视图函数处理请求,返回参数username对应用户的被关注者。

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

5.followers.html模板

    我们看main.followers视图函数最后的返回语句:

       

return render_tempalte('followers.html', user=user, title="Followers of", follows=follows, endpoint=".followers", pagination=pagination)

    我们返回的前两个参数, 供followers页面的标题使用, 第三个参数是该用户所有的关注者, 显示在一个table里, 最后两个参数供分页使用, 我们点击Followers按钮时想得到这样一个页面:

   


{% extends "base.html" %}

{% import "_micros.html" as micros %}


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


{% block page_content %}

<div class="page-header">

    <h1>{{ title }}{{ user.username }}</h1>

</div>

<table>

    <thead>

        <tr>

            <th>User</th>

            <th>Since</th>

        </tr>

    </thead>

    {% for follow in follows%}

        {% if follow['user'] != user %}

            <tr>

                <td>

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

                        <img class="img-rounded" src="{{ follow['user'].gravatar(size=32) }}">

                        {{ follow['user'].username }}

                    </a>

                </td>

                <td>

                    {{ moment(follow['timestamp']).format('L') }}

                </td>

            </tr>

        {% endif %}

    {% endfor %}

</table>

<div class="pagination">

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

</div>

{% endblock %}

6. 补充

    followers.html页面里面的宏, 代码如下, 宏的**kwargs参数自动传递:

{% macro pagination_widget(pagination, endpoint) %}
<ul class="pagination">
    <li {% if not pagination.has_prev %} class="disabled" {% endif %}>
        <a href="{% if pagination.has_prev %} {{ url_for(endpoint, page=pagination.page - 1, **kwargs)}} {% else %} # {% endif %}">
          «
        </a>
    </li>
    {% for p in pagination.iter_pages() %}
        {% if p %}
            {% if p == pagination.page %}
            <li class="active">
                <a href="{{ url_for(endpoint, page=p, **kwargs) }}">{{ p }}</a>
            </li>
            {% else %}
            <li>
                <a href="{{ url_for(endpoint, page=p, **kwargs) }}">{{ p }}</a>
            </li>
            {% endif %}
        {% else %}
        <li class="disabled"><a href="#">…</a></li>
        {% endif %}
    {% endfor %}
    <li {% if not pagination.has_next %} class="disabled" {% endif %}>
        <a href="{% if pagination.has_next %} {{ url_for(endpoint, page=pagination.page+1, **kwargs) }} {% else %} # {% endif %}">
            »
        </a>
    </li>
</ul>
{% endmacro %}



   




猜你喜欢

转载自blog.csdn.net/sinat_34927324/article/details/80065143