我的网站搭建(第44天) 添加头像字段

  • 发布时间:2017年2月20日 14:50
  • 作者:杨仕航
* 该文是基于Python2.7开发的,最新Python3.x和Django2.x视频教程可以前往 >> Django2.0视频教程

马斯洛说需求是逐阶段递增的。满足网站的基本需求之后,下一步是美化和优化网站。

我博文评论区的UI很简陋。之前还凑合用,现在看不下去,需要优化。

琢磨了一番,准备弄成类似贴吧和聊天框结合的样式。不过,这些需要头像。

所以,优化之前要先给我网站的用户添加头像功能。


添加头像需要考虑很多东西,例如如何上传头像、更新头像之后如何及时更新缓存等等问题。

和头像相关的django库有django-avatar和django-imagekit。

django-avatar是提供Gravatar全球头像服务。这里我不需要使用该功能,直接使用默认头像即可。

django-imagekit是处理上传的图片,生成图片多种尺寸的缓存。由于头像的图片我只需要64*64的规格,暂时不想用该功能。

上传图片之后,再用pli.image处理即可。

而且每次用户上传更新头像,我给头像图片重新命名新的文件名。就可以解决本地缓存问题。(当然,你用动态链接获取头像也可以。)


问题考虑差不多,可以准备动手写代码。

我的用户系统是使用Django自带的用户系统。该系统没有头像相关字段,需要拓展用户模型。

这里建议新建应用和模型,用一对一字段和Django的用户模型关联。这种方式叫profile方法。

比较安全和保险。


创建一个user_ex应用,前面在我的网站搭建(第21天) 找回密码中已经创建。

打开models.py,加入新的模型如下:

#coding:utf-8
from django.db import models
from django.contrib.auth.models import User

#头像上传目录(后面很涉及到头像操作,用变量统一管理)
AVATAR_ROOT = 'static/media/avatar'

class User_Avatar(models.Model):
    """user avatar"""
    user = models.ForeignKey(User)
    avatar = models.ImageField(upload_to=AVATAR_ROOT)


添加模型之后,再更新数据库。

python manage.py makegirations
python manage.py migrate


此时,我网站中任何用户都没有设置头像,需要一个默认头像。

在我存放头像的目录下,放了一个默认头像。

获取头像的时候,判断在User_Avatar模型中是否存在对应的头像。若不存在,则取该默认头像作为头像。

问题来了,我至少有3个地方需要获取头像:登录之后显示头像和用户名、个人中心显示头像和评论区显示头像。

而且这3个地方的代码都不在同一个文件。若每个文件我都需要导入User_Avatar模型并判断是否有设置对应头像,返回设置的头像或返回默认的头像。这样显得代码很冗余且不利于维护。

若封装成一个函数,这3个文件都需要导入这个函数。该方法也是有点麻烦。若是可以把获取头像的方法弄成User模型的方法就好了。

当然可以,我们可以给类实例化之后的对象绑定方法。


我在开发该功能的过程中,测试在models.py文件中写入代码。在项目加载的时候会被执行。

20170220/20170220143843367.jpg

从上图中,可以看出会被执行,而且还执行了两次。

写个方法,动态绑定。测试如下图:

20170220/20170220144020242.jpg

可以看到,获取user对象之后可以使用绑定的get_avatar_url方法。

那么,我可以用该方法把获取头像的代码绑定到User模型中。models.py完整代码如下

#coding:utf-8
from django.db import models
from django.contrib.auth.models import User

from types import MethodType #类动态绑定方法
import os

AVATAR_ROOT = 'static/media/avatar'
AVATAR_DEFAULT = os.path.join(AVATAR_ROOT, 'default_64.png')

class User_Avatar(models.Model):
    """user avatar"""
    user = models.ForeignKey(User)
    avatar = models.ImageField(upload_to=AVATAR_ROOT)


#动态绑定头像相关的方法
def get_avatar_url(self):
    try:
        avatar = User_Avatar.objects.get(user=self.id)
        return avatar.avatar
    except Exception as e:
        return AVATAR_DEFAULT

#动态绑定方法
User.get_avatar_url = MethodType(get_avatar_url, None, User)

后面设置头像的代码也可以用该方法绑定到User中。

最后,先在网站的导航栏测试能否显示默认头像。

判断并返回登录状态的代码可以参考我的网站搭建(第13天) 用户认证:前言

获取用户对象之后,用user.get_avatar_url()获取头像路径。

最后,html页面效果如下:

20170220/20170220144856350.png

可以正常获取,接下来继续开发,写上传头像功能。

上一篇:Python用win32api操作注册表

下一篇:VSTO窗体在Word内弹窗置顶

相关专题: Django评论库开发   

评论列表

智慧如你,不想发表一下意见吗?

新的评论

清空