Flask 教程,第六部分:个人资料和头像 已翻译 100%

oschina 投递于 2012/12/28 09:27 (共 19 段, 翻译完成于 01-15)
阅读 13504
收藏 7
0
加载中

在我发表自己用Python语言中的Flask轻量级框架开发web项目经验系列文章中,这已经是第六篇了。

这一些列教程的目的主要是为了来开发一个比较得体并具有特色的微博客应用程序,由于-缺少原创性,-所以称它为微博客。

下面是此系列教程中目前-已发布的所有-文章目录列表:

旋转360
翻译于 2013/01/15 08:50
1

概要

在此教程的前面章节中我们已经把登陆系统做好了,现在用户可以使用OpenI使用来登陆和退出系统了。

今天,我们来做用户资料模块,我们需要创建一个用户资料的页面来显示用户的详细信息和他最近发表的博客,还有展示用户头像。

然后我们将创建一个用户资料编辑web表单页面。

旋转360
翻译于 2013/01/15 08:50
1


用户资料页面

在用户资料页面,基本上没有什么特别要强调和介绍的新概念。只需要创建一个含有HTML的新视图函数模板页面即可。

下面是视图函数(项目目录/views.py:

@app.route('/user/<nickname>')
@login_required
def user(nickname):
    user = User.query.filter_by(nickname = nickname).first()
    if user == None:
        flash('不存在用户:' + nickname + '!')
        return redirect(url_for('index'))
    posts = [
        { 'author': user, 'body': 'Test post #1' },
        { 'author': user, 'body': 'Test post #2' }
    ]
    return render_template('user.html',
        user = user,
        posts = posts)

这里的@app.route标识主要是用来说明此视图函数不同于之前的那些。我们定义了一个名为<nickname>的参数。在函数里面它会转化成跟它同名的参数,当用户有请求的时候,例如这样的一个URLURL/user/miguel,次视图函数就会识别为有一个名为nickname值为'miguel'的参数,即nickname = 'miguel'

旋转360
翻译于 2013/01/15 08:52
3



没必要为此方法的实现过程感到惊讶。首先我们需要通过把转化后的nickname参数作为条件,尝试着从数据库里把此用户的数据调用出来。如果没有查询到数据,我们就像之前那样,给用户一个错误的提示并且跳转到主页去。



一旦我们找到了改用户,我们就在模板下面来显示该用户的文章。要注意下的是在用户资料页面我们只让显示该用户的文章,所以文章的作者要是该用户。



初始化的视图模板非常的简单(项目目录/templates/user.html):



<!-- extend base layout -->
{% extends "base.html" %}

{% block content %}
<h1>用户昵称: {{user.nickname}}!</h1>
<hr>
{% for post in posts %}
<p>
  {{post.author.nickname}} 发布了: <b>{{post.body}}</b>
</p>
{% endfor %}
{% endblock %}


旋转360
翻译于 2013/01/15 08:53
2

用户资料页面就做好了,不过在站点中还没有指向改页面的链接地址。为了让用户很方便的来查看自己的资料信息我们就把链接地址放到最上面的导航上去(项目目录/templates/base.html):


<div>Microblog:
        <a href="{{ url_for('index') }}">Home</a>
        {% if g.user.is_authenticated() %}
        | <a href="{{ url_for('user', nickname = g.user.nickname) }}">你的个人资料</a>
        | <a href="{{ url_for('logout') }}">退出登陆</a>
        {% endif %}
    </div>

注意一下我们已经给函数传参了之后的和之前的URL

现在就来试一试这个项目。点击上面的你的资料链接就会跳转到用户资料页面。由于我们还没有指向一个随意用户资料页面的链接地址,所以在这里如果你想看他人的资料,就需要自己手动输入一下地址了。比如你想看miguel的资料,那么地址就是:http://localhost:5000/user/miguelt

旋转360
翻译于 2013/01/15 08:54
1


头像部分

我相信你会觉得目前的用户资料页面看起来很单调。为了好看,我们就来添加用户头像的功能。

为了避免我们服务器需要来处理大量上传后的头像图片,我们在这里就使用Gravatar给咋们提供的用户头像即可。

鉴于返回一个用户头像是属于用户这块的,所以我们就把代码放在theUserclass里面(项目目录/models.py:

from hashlib import md5
# ...
class User(db.Model):
    # ...
    def avatar(self, size):
        return 'http://www.gravatar.com/avatar/' + md5(self.email).hexdigest() + 
        '?d=mm&s=' + str(size)

avatar将会返回用户头像图片的地址根据你的需要来请求你想要的图片尺寸像素。

旋转360
翻译于 2013/01/15 08:55
1

Gravatar上得到图像图片很简单。你只需要用md5把用户的邮箱hash加密之后合并成上面的那种url形式即可。当然你也可以自由选择自 定义图像大小。其中“d=mm”是设置用户在没有Gravatar账号的情况下显示的默认头像。“mm”选项会返回一张只有人轮廓的灰色图片,称之为谜 样人。而“s=”选项是用来设置返回你给定的图片尺寸像素。

当然Gravatar也有自己的文档来描述URL的拼接技术!

旋转360
翻译于 2013/01/15 08:56
1


到这里Userclass就可以返回一个用户头像的图片了,我们就需要把这个整合到用户资料布局去(项目目录/templates/user.html:

<!-- extend base layout -->
{% extends "base.html" %}

{% block content %}
<table>
    <tr valign="top">
        <td><img src="{{user.avatar(128)}}"></td>
        <td><h1>用户昵称: {{user.nickname}}</h1></td>
    </tr>
</table>
<hr>
{% for post in posts %}
<p>
  {{post.author.nickname}} 发布了: <b>{{post.body}}</b>
</p>
{% endfor %}
{% endblock %}

我们设计Userclass来返回用户头像的亮点在于:如果某一天我们要是觉得Gravatar网站上的头像不是我们所想要的头像的时候,我们只需要我们只需要重写一下头像处理的函数来返回我们想要的地址即可(即使有人盗链指向我们的服务器,我们也可以保护好自己的主机),这样一来只需要修改这么点点,所以的模板都还是自动正常运行。

旋转360
翻译于 2013/01/15 08:57
1

我们已经把用户头像部分添加到了用户资料详情页面的顶部去了,不过在页面底部我们还有显示文章的没做,在文章前面我们也需要显示一下用户的头像。当 然在用户资料页面需要对所以的文章都显示同样的头像,不过要是把头像函数移动到主页去来给所以的文章都显示作者的头像,那该多好。

我们只需要稍稍修改模板文件即可实现给文章显示相应作者头像的功能(项目目录/templates/user.html:

<!-- extend base layout -->
{% extends "base.html" %}

{% block content %}
<table>
    <tr valign="top">
        <td><img src="{{user.avatar(128)}}"></td>
        <td><h1>用户昵称: {{user.nickname}}</h1></td>
    </tr>
</table>
<hr>
{% for post in posts %}
<table>
    <tr valign="top">
        <td><img src="{{post.author.avatar(50)}}"></td><td><i>{{post.author.nickname}}
     发布了:</i><br>{{post.body}}</td>
    </tr>
</table>
{% endfor %}
{% endblock %}

这就是到此为止我们的用户资料页面:

微博客用户详情页面


旋转360
翻译于 2013/01/15 08:58
1


重复使用子模板

用户资料页面显示了用户自己的文章,不过网站的首页需要显示此刻不同用户文章。在这里就有两个用于显示 用户文章的模板文件了。我们可以直接复制把处理显示文章的那段代码然后直接粘贴到新的模板,其实那并不是最理想的方法,倘若有一天我们需要修改下显示文章 那块,我们就需要来更新所以的那些含有文章显示代码的模板文件。

旋转360
翻译于 2013/01/15 08:59
1
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接。
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。
加载中

评论(10)

初入坑
初入坑

引用来自“初入坑”的评论

下载源码后,运行没错,进入 localhost:5000/ 报错:TypeError: 'bool' object is not callable
问题出现在这句:if g.user.is_authenticated():,但是上一章的源码没有错误,这是什么问题?

引用来自“HQNY”的评论

由于版本的原因,方法:is_authenticated()已变为:is_authenticated 属性,所以将if g.user.is_autenticated()改为 if g.user.is_authenticated 即可。
嗯。谢谢哦。
HQNY
HQNY
ImportError: No module named flask.ext.openid,求助
HQNY
HQNY

引用来自“初入坑”的评论

下载源码后,运行没错,进入 localhost:5000/ 报错:TypeError: 'bool' object is not callable
问题出现在这句:if g.user.is_authenticated():,但是上一章的源码没有错误,这是什么问题?
由于版本的原因,方法:is_authenticated()已变为:is_authenticated 属性,所以将if g.user.is_autenticated()改为 if g.user.is_authenticated 即可。
初入坑
初入坑
下载源码后,运行没错,进入 localhost:5000/ 报错:TypeError: 'bool' object is not callable
问题出现在这句:if g.user.is_authenticated():,但是上一章的源码没有错误,这是什么问题?
h
hzxscyq

引用来自“likeyi”的评论

不知道有哪些bug呀? 跟到这一章了,除了openid没有用(也用不了),其他的都走到这一步了,继续下一关。

引用来自“ay27”的评论

openid可以用openid.org.cn,在上面申请个openid就行了
我申请了一个为什么还是没有用.....
a
ay27

引用来自“likeyi”的评论

不知道有哪些bug呀? 跟到这一章了,除了openid没有用(也用不了),其他的都走到这一步了,继续下一关。
openid可以用openid.org.cn,在上面申请个openid就行了
likeyi
likeyi
不知道有哪些bug呀? 跟到这一章了,除了openid没有用(也用不了),其他的都走到这一步了,继续下一关。
旋转360
旋转360

引用来自“虫虫”的评论

引用来自“xz360”的评论

有的地方翻译不是很到位,望指出来一起给个合理的翻译,谢谢!

根据自己的理解翻译是最好的。实在无法翻译的地方可以忽略。

嗯,以后注意下!我以为必须要原文翻译呢,哈哈!
虫虫
虫虫

引用来自“xz360”的评论

有的地方翻译不是很到位,望指出来一起给个合理的翻译,谢谢!

根据自己的理解翻译是最好的。实在无法翻译的地方可以忽略。
旋转360
旋转360
有的地方翻译不是很到位,望指出来一起给个合理的翻译,谢谢!
返回顶部
顶部