关于本站
1、基于Django+Bootstrap开发
2、主要发表本人的技术原创博客
3、本站于 2015-12-01 开始建站
前面开发了QQ、新浪微博和Github第三方登录,即OAuth。上次又给用户添加了头像。
那么问题来了:如果从未在我网站注册用户,直接用OAuth第三方注册并登录之后没有头像。
用户还需要自己手动再设置头像。这点对用户来说有些麻烦,用户体验不是很好。
我们可以改进为:若用第三方社交账号登录,则使用该第三方账号的头像作为我网站该用户账号的头像。
Django的OAuth相关文章前面有了,这里就不在赘述。有兴趣可以先看看这些文章。
我使用的用户系统是Django自带的用户系统。Django的用户系统没有头像字段和功能,我对其相关做了一些拓展。文章如下:
我的网站搭建(第47天) 修改评论列表的样式(头像的使用)
为了避免重复设置头像,需要判断用户是否已经设置了头像。
同样使用给类动态绑定函数的方法,给User用户类绑定判断是否有头像的函数。(可见我的网站搭建(第44天) 添加头像字段)
该方法可以大大简化代码结构。我给User拓展添加了一个User_Avatar模型,用于管理用户头像。
添加判断代码写在models.py文件中,如下所示:
#coding:utf-8 from django.db import models from django.contrib.auth.models import User from types import MethodType #类动态绑定方法 class User_Avatar(models.Model): """用户头像拓展模型""" user = models.ForeignKey(User) avatar = models.ImageField(upload_to=AVATAR_ROOT) def has_avatar(self): """判断是否有设置头像""" return User_Avatar.objects.filter(user=self.id).count() > 0 #动态绑定方法 User.has_avatar = MethodType(has_avatar, None, User)
ps:前面的文章中,我还动态绑定当前用户头像和设置用户头像的方法。
OAuth相关代码太多了,这个请看上面罗列的OAuth相关博文。
我还进一步对OAuth代码整理。这个我会在我的Django视频教程中详细讲解(课程还在录制中,没那么快)
不同的第三方账号获取头像的位置大致相同,都是获取账号用户信息。
在账号用户信息中就附带了头像链接。相应的API如下:
QQ的OAuth获取用户信息:http://wiki.open.qq.com/wiki/website/get_user_info
新浪的OAuth获取用户信息:http://open.weibo.com/wiki/2/users/show
Github的OAuth获取用户信息:https://developer.github.com/v3/users/
以QQ为例,在获取QQ用户信息返回数据如下:
其中,我们可以使用figureurl_qq_1参数值获取一个40*40的头像。
获取头像代码如下:
#coding:utf-8 import os, re, json, time import urllib, urllib2, urlparse import uuid from django.conf import settings class OAuth_QQ(OAuth_Base): #还有其他相关代码,可参考前面写的OAuth相关博文 user_info = {} #头像保存的临时目录 temp_folder = os.path.join(settings.BASE_DIR, 'static', 'temp') def get_user_info(self): """获取QQ用户的资料信息""" if not self.user_info: params = {'access_token': self.access_token, 'oauth_consumer_key': self.client_id, 'openid': self.openid} response = self._get(self.url_user_info, params) self.user_info = json.loads(response) return self.user_info def download_avatar(self): """下载头像图片""" if not self.user_info: self.get_user_info() #获取头像链接 40*40 url = self.user_info['figureurl_qq_1'] filename = os.path.join(self.temp_folder, uuid.uuid1().hex + '.jpg') #下载头像图片 urllib.urlretrieve(url, filename) return filename
这里,统一把头像下载到临时目录,并用uuid随机设置文件名。
而且不管下载头像是什么图片格式,统一写jpg格式。(不用担心待会裁剪图片格式问题,PIL读取图片格式会自动识别)
由于download下来的头像尺寸不一定是64*64,需要对头像进一步处理。
这里我也优化了前面博文写的裁剪图片代码,将该部分代码拆分出来。
def _cut_save_avatar(user, temp_path, left=0, top=0, width=0, height=0): #python2.7 pillow from PIL import Image im = Image.open(temp_path) #裁剪图片 if width==0 or height==0: right, bottom = im.size else: right = left + width bottom = top + height crop_im = im.convert("RGBA").crop((left, top, right, bottom)).resize((64, 64), Image.ANTIALIAS) #设置背景颜色为白色 out = Image.new('RGBA', crop_im.size, (255,255,255)) out.paste(crop_im, (0, 0, 64, 64), crop_im) #保存图片 out.save(temp_path) #保存记录 avatar = user.set_avatar_url(temp_path) os.remove(temp_path) #返回头像路径 return avatar.avatar.url
结合下载头像的代码,就可以实现OAuth登录并自动获取和应用头像功能。代码如下:
def _check_oauth_avatar(user, oauth): """OAuth登录,头像处理""" #判断头像是否存在 if not user.has_avatar(): try: temp_path = oauth.download_avatar() #获取并下载头像到本地 _cut_save_avatar(user, temp_path) #裁剪并保存头像 except Exception as e: print(e.message) return True
只需要传递user对象和自己写的oauth对象即可。并在OAuth登录成功之后,执行一下该方法即可。