正在给网站增加“用豆瓣登录”功能,遇到一些问题,求指导。

2012-12-15 19:09:41 +08:00
 paloalto
网站之前有用户注册功能,为了让豆瓣用户更方便的登录到我的网站上,最近正在增加“用豆瓣登录”功能,

原先的用户注册功能,是把用户的 username、email、nickname、password 信息存到 users 表中,其他的年龄、地址、简介等信息存到 profile 表中。

原先的注册、登录功能很久之前就已经写完,其他的功能也都搞定,可以说网站已经做完了。

但是后来在增加”用豆瓣登录“功能时,发现豆瓣返回的用户信息和我上面写的数据表结构不一致,比如,豆瓣返回的数据是这样的,和我的users表数据结构不一致:

"id": "1000001",
"uid": "ahbei",
"name": "阿北",
"avatar": "http://img3.douban.com/icon/u1000001-28.jpg", //头像小图
"alt": "http://www.douban.com/people/ahbei/",
"relation": "contact", //和当前登录用户的关系,friend或contact
"created": "2006-01-09 21:12:47", //注册时间
"loc_id": "108288", //城市id
"loc_name": "北京", //所在地全称
"desc": "现在多数时间在忙忙碌碌地为豆瓣添砖加瓦。坐在马桶上看书,算是一天中最放松的时间。”

于是为了不和以前的 users 表冲突,我又新建了一个 douban_users 表,用来单独存储用豆瓣登录的用户。目前已经能够把用豆瓣登录的用户信息保存到数据库 douban_users 表中。

可以说目前为止一切正常。

但是。。。

查询用户的时候就出现麻烦了,因为不知道如何解决以下问题,所以发帖请教:

因为现在查询用户的相关代码都是查询的 users 表,比如获取昵称、头像神马的,增加了这个 douban_users 表之后,就得先判断这个用户是不是通过豆瓣登录的,如果是,就去查询douban_users;如果不是,就去查原先的users表。想到这里,我觉得不对劲,所以就没有继续往下写代码。

虽然我知道能通过以上的判断来解决问题,但是总觉得这么做不是最好的解决办法。而且如果以后再增加”用新浪微博登录“、”用腾讯微博登录“啥的,返回的数据结构再不一样的话,就又要重新建表,再增加一个判断。

不知道大家在处理类似”用豆瓣登录“这种功能的时候,有没有遇到这样的问题?
3277 次点击
所在节点    编程
13 条回复
talentsnail
2012-12-15 19:30:19 +08:00
只保存你的users表中已有的字段信息,再给users表加上一个用户来源的字段,本站注册的为0,豆瓣1,微博2……
这样可以不?
paloalto
2012-12-15 19:34:40 +08:00
@talentsnail 是个解决办法。等我找找看还有没有其他的方案。。
ksky
2012-12-15 19:38:01 +08:00
给豆瓣用户创建一个新用户在你之前的用户表里通用信息存一起,然后关联到新的豆瓣用表里。
paloalto
2012-12-15 19:53:30 +08:00
@ksky 你的意思是说把 usename \ nickname 等通用信息都存到users表,把其他豆瓣独有的字段存到douban_users表,两张表通过某个共有的字段关联起来,是这样吗?
ksky
2012-12-15 22:49:39 +08:00
@paloalto 我的意思是,你还是用一个表来查询所有用户,如果你想要完整的豆瓣用户的资料就单独建表存储,在users表里加字段关联起来就行了。以后加新浪微博登录也可以同样处理。
ergatea
2012-12-16 01:32:16 +08:00
base user
(key username、email、nickname、password )

douban user info
(base user key ...)
paloalto
2012-12-16 02:27:23 +08:00
感谢
@ergatea
@ksky
@talentsnail
三位的解答。

我打算综合三位的方案, users 表中增加一个来源字段,原始注册是0,豆瓣是1,新浪是2...主要是考虑到这样,就可以根据来源字段来判断需要是否需要拼接头像的连接地址,比较方便一些。因为原始注册时,我是在 users 的 avatarPath 字段里存了部分路径,需要调用头像时就在前端拼接:

$if user.avatarPath:
----$ src = '/static/upload/image' + user.avatarPath + '_48.jpg'
----<img src="$src" width="30" alt="$user.nickname" />
$else:
----<img src="/static/public/img/default_48x48.jpg" width="30" alt="$user.nickname" />

以后再加一个判断就可以了:

$if user.avatarPath:
----$if user.via == 0 #原始注册
--------$ src = '/static/upload/image' + user.avatarPath + '_48.jpg'
--------<img src="$src" width="30" alt="$user.nickname" />
----$if user.via == 1 #豆瓣
--------$ src = user.avatarPath
--------<img src="$src" width="30" alt="$user.nickname" />
$else:
----<img src="/static/public/img/default_48x48.jpg" width="30" alt="$user.nickname" />

另外,把豆瓣的uid 当做 username,nickname = nickname,存储到users表中,其他的个人简介和常居地什么的就放到原先的 profile 表中,因为之前 users 和 profile 俩表就是关联的。

这样就不用再新建一个douban_users表,全部通过一个 users 表来实现了。
ergatea
2012-12-16 22:29:21 +08:00
擴展你的 user class 添加 get_avatar 方法,把你的邏輯寫在裏面,至於表結構合方式都是可以接受的,都可以,關於 get 過來的 api 數據,本人不建議大量存儲關係數據庫,存放cache系統應該可以滿足你的需求了。


下面是我的model代碼, accesstoken表主要就是存儲用戶的api信息。
======

class AccessToken(db.Model):
__tablename__ = 'accesstoken'
id = db.Column(db.Integer, primary_key = True)
email = db.Column(db.String(100))
service = db.Column(db.String(50))
token = db.Column(db.String)
token_secret = db.Column(db.String)

class User(db.Model):
__tablename__ = 'users'
id = db.Column(db.String(40), primary_key=True)
email = db.Column(db.String(100), unique=True)
username = db.Column(db.String(50), unique=True)
password = db.Column(db.String(40))
activate = db.Column(db.Boolean)
join_date = db.Column(db.DateTime)
tags = db.relationship('Tag', secondary=book_tag,
backref=db.backref('users', lazy='dynamic'))


class Profile(db.Model):
pass
paloalto
2012-12-17 01:25:01 +08:00
@ergatea 谢谢你的回答!另外问一个问题,从豆瓣过来的用户的用户名可能会跟我网站中的用户名有重复,所以我想在存储豆瓣用户的数据之前,先检查一下数据库中是否已经存在有相同的用户名了,如果有,就给新用户的用户名后面加一个后缀“_1”。

#判断username是否有重名
if not users.is_username_available(username):
----username = username + '_1'

但是这样只能顶一次用。比如:
用户在豆瓣的用户名是 ahbei ,恰巧我的网站中也有一个 ahbei 。按照上面的代码,这位新用户用豆瓣登录后,存储在数据库中的用户名会变成 ahbei_1;但是如果后来又有一个叫 ahbei_1 的豆瓣用户过来了,按照上面的程序,这位用户的用户名就会变成 ahbei_1_1。 —— 但其实我是想让他变成 ahbei_2的。

请问怎么才能在遇到有重复的用户名之后让新用户名后面的那个数字递增呢?
paloalto
2012-12-17 07:26:31 +08:00
目前的解决方案是先把原始注册关闭了,只开放“用豆瓣登录”功能。
ergatea
2012-12-17 19:31:17 +08:00
你把簡單的事情複雜了,你完全可以別去判斷username,這種重複率很高的項,你的用戶如果是註冊用戶,那麼你讓他自己來授權api登錄,如果不是如果還沒註冊,你可以在用戶使用api登錄後讓系統自己建立一個用戶,你說對嗎?
paloalto
2012-12-17 19:40:06 +08:00
@ergatea 不好意思,你说的我没明白。
你的意思是给使用原始方式进行注册的用户增加一个绑定豆瓣帐号的功能?
ergatea
2012-12-17 22:41:13 +08:00
可以這麼理解。如果是網站註冊用戶,就讓他選擇是否綁定API登入服務,反之則通過API登入後由系統建立用戶信息。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/54990

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX