the flask mega tutorial自学记录 之 第六章 Profile Page(个人信息页)


本章介绍构建一个用户个人信息页,同时可以针对个人信息进行编辑更新。
Tip:在个人信息页的模板中,我自己把img元素换成本地的图片相对路径表达式,图片显示不出来。可能这跟框架有关系,需要把图片换成url引用格式。

一、用户个人信息页

1、构建个人信息页,在路由中设置url,带有user参数:
http:/…?user=username。

@app.route('/user/<username>')    #<username>参数:可以传给user视图函数
@login_required
def user(username):
#first_or_404:返回查询的第一个结果,如果未查到,返回404。
    user = User.query.filter_by(username=username).first_or_404()
    posts = [
        {'author': user, 'body': 'Test post #1'},
        {'author': user, 'body': 'Test post #2'}
    ]
    return render_template('user.html', user=user, posts=posts)

2、构建个人信息html。

{% extends "base.html" %}

{% block content %}
    <h1>User: {{ user.username }}</h1>
    <hr>
    {% for post in posts %}
    <p>
    {{ post.author.username }} says: <b>{{ post.body }}</b>
    </p>
    {% endfor %}
{% endblock %}

3、为了方便用户查看自己信息,在导航栏增加一个菜单“Profile”。

    <div>
      Microblog:
      <a href="{{ url_for('index') }}">Home</a>
      {% if current_user.is_anonymous %}
      <a href="{{ url_for('login') }}">Login</a>
      {% else %}
      <a href="{{ url_for('user', username=current_user.username) }}">Profile</a>
      <a href="{{ url_for('logout') }}">Logout</a>
      {% endif %}
    </div>

二、Avatars

Gravatar提供一个图片服务。用户可以通过邮箱来关联一张图片。默认提供的图片的大小是8080px。它提供了一个接口来访问图片: https://www.gravatar.com/avatar/…/s=。s代表图片的大小。
1、在用户信息界面增加图片
app/templates/user.htm

{% extends "base.html" %}

{% block content %}
    <table>
        <tr valign="top">
            <td><img src="{{ user.avatar(128) }}"></td>
            <td><h1>User: {{ user.username }}</h1></td>
        </tr>
    </table>
    <hr>
    {% for post in posts %}
    <p>
    {{ post.author.username }} says: <b>{{ post.body }}</b>
    </p>
    {% endfor %}
{% endblock %}

三、Jinja2子模板

除了在个人信息页用到文章呈现格式,在首页也同样保留这种风格。根据独立性原则,可以为这种公用部分做成一个子模板。
app/templates/_post.html:

    <table>
        <tr valign="top">
            <td><img src="{{ post.author.avatar(36) }}"></td>
            <td>{{ post.author.username }} says:<br>{{ post.body }}</td>
        </tr>
    </table>

在个人信息页把通用部分用子模板代替。
{% include ‘_post.html’ %}:切入子模板。

{% extends "base.html" %}

{% block content %}
    <table>
        <tr valign="top">
            <td><img src="{{ user.avatar(128) }}"></td>
            <td><h1>User: {{ user.username }}</h1></td>
        </tr>
    </table>
    <hr>
    {% for post in posts %}
        {% include '_post.html' %}
    {% endfor %}
{% endblock %}

四、更有意思的个人信息

1、增加两个信息:个人签名及上次时间。
app/models.py:

class User(UserMixin, db.Model):
    # ...
    about_me = db.Column(db.String(140))
    last_seen = db.Column(db.DateTime, default=datetime.utcnow)

一旦数据库结构发生变动,我们就需要migrate及upgrade数据库。
4、重新设计个人信息页

{% extends "base.html" %}

{% block content %}
    <table>
        <tr valign="top">
            <td><img src="{{ user.avatar(128) }}"></td>
            <td>
            <h1>User: {{ user.username }}</h1>
            {% if user.about_me %}<p>{{ user.about_me }}</p>{% endif %}
            {% if user.last_seen %}<p>Last seen on: {{ user.last_seen }}</p>{% endif %} 
            </td>
        </tr>
    </table>
    <hr>
    {% for post in posts %}
        {% include '_post.html' %}   #Jinja2's include语法
    {% endfor %}
{% endblock %}

五、记录用户上次访问时间

在视图函数中,我们可以把网页发起request时的时间记录到last_seen字段。
但是当网页很多,如果在每个页面视图中都加入这种记录方法,那是不太切实际的。
所以,可以有一种更智慧的替代方法:
app/routes.py:

from datetime import datetime

@app.before_request
def before_request():
    if current_user.is_authenticated:
        current_user.last_seen = datetime.utcnow()
        db.session.commit()

@app.before_request:这个装饰器的作用是可以在发起request前执行我们定义的代码。

六、个人信息编辑页

1、设置编辑页Form结构
app/forms.py:

from wtforms import StringField, TextAreaField, SubmitField
from wtforms.validators import DataRequired, Length

# ...

class EditProfileForm(FlaskForm):
    username = StringField('Username', validators=[DataRequired()])
    about_me = TextAreaField('About me', validators=[Length(min=0, max=140)])
    submit = SubmitField('Submit')

validators=[Length(min=0, max=140)]:定义多行文本框的字数范围。
2、设计编辑页Html:用户可以修改名称,添加或编辑个人描述信息。
app/templates/edit_profile.html:

{% extends "base.html" %}

{% block content %}
    <h1>Edit Profile</h1>
    <form action="" method="post">
        {{ form.hidden_tag() }}
        <p>
            {{ form.username.label }}<br>
            {{ form.username(size=32) }}<br>
            {% for error in form.username.errors %}
            <span style="color: red;">[{{ error }}]</span>
            {% endfor %}
        </p>
        <p>
            {{ form.about_me.label }}<br>
            {{ form.about_me(cols=50, rows=4) }}<br>
            {% for error in form.about_me.errors %}
            <span style="color: red;">[{{ error }}]</span>
            {% endfor %}
        </p>
        <p>{{ form.submit() }}</p>
    </form>
{% endblock %}

3 、设置扉页编辑视图函数
app/routes.py

from app.forms import EditProfileForm

@app.route('/edit_profile', methods=['GET', 'POST'])
@login_required
def edit_profile():
    form = EditProfileForm()
    if form.validate_on_submit():
        current_user.username = form.username.data
        current_user.about_me = form.about_me.data
        db.session.commit()         #把新值传入数据库
        flash('Your changes have been saved.')
        return redirect(url_for('edit_profile'))
    elif request.method == 'GET':
        form.username.data = current_user.username
        form.about_me.data = current_user.about_me
    return render_template('edit_profile.html', title='Edit Profile',
                           form=form)

4 、在用户扉页最底下增加一个“”编辑个人信息页链接”
app/templates/user.html:

  {% if user == current_user %}
                <p><a href="{{ url_for('edit_profile') }}">Edit your profile</a></p>
                {% endif %}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值