def get_top_n(RANK_NUM): '''获取排行榜前n名的用户数据''' # 从redis里取出原始数据 origin_data = rds.zrevrange(keys.HOT_RANK, 0, RANK_NUM - 1, withscores=True) # 原始数据转换成int类型 cleaned_data = [[int(uid), int(score)] for uid, score in origin_data] # 用户的id列表 uid_list = [item[0] for item in cleaned_data] # 数据库取数据 users = User.objects.filter(id__in=uid_list) users = sorted(users, key=lambda user: uid_list.index(user.id)) # 整理数据 rank_data = [] for index, (uid, score) in enumerate(cleaned_data): rank = index + 1 user = users[index] user_data = user.to_dict( exclude=['phonenum', 'birthday', 'location', 'vip_id', 'vip_end']) user_data['rank'] = rank user_data['score'] = score rank_data.append(user_data) return rank_data
def get_top_n(num): '''获取全服热度前 N 的用户数据''' # 从 Redis 中取出原始排行数据 origin_data = rds.zrevrange(keys.HOT_RANK_K, 0, num - 1, withscores=True) # 对原始排名数据进行类型转换 # rank_data = [ # [53, 4953], # [60, 4852], # [96, 4814], # [11, 4586], # ... # ] rank_data = [[int(uid), int(score)] for uid, score in origin_data] # 取出每一项的 uid, 获取每个用户的信息 uid_list = [uid for uid, _ in rank_data] users = User.objects.filter(id__in=uid_list) users = sorted(users, key=lambda user: uid_list.index(user.id)) # 将 users 按照 uid_list 的顺序排列 # 组装结果数据 result = {} for idx, user in enumerate(users): rank = idx + 1 user_info = user.to_dict(exclude=['phonenum', 'birthday', 'location', 'vip_id', 'vip_end']) user_info['score'] = rank_data[idx][1] result[rank] = user_info return result
def get_top_n(num): '''获取积分排行最高的前 N 个用户''' # 取出原始榜单数据 rank_data = rds.zrevrange(keys.RANK_K, 0, num - 1, withscores=True) cleaned_rank = [[int(uid), int(score)] for uid, score in rank_data] # 对原始数据进行简单清洗 # 取出所有的用户数据 uid_list = [uid for uid, _ in cleaned_rank] # 取出每个用户 UID users = User.objects.filter(id__in=uid_list).only('id', 'nickname', 'avatar') users = sorted( users, key=lambda user: uid_list.index(user.id)) # 按照 uid 在 uid_list 中的顺序重新排列 # 组装数据 result = {} for index, (uid, score) in enumerate(cleaned_rank): rank = index + 1 user = users[index] user_dict = { 'id': uid, 'score': score, 'nickname': user.nickname, 'avatar': user.avatar, } result[rank] = user_dict return result
def get_top_n(num): """获取排行榜前 N 的用户数据""" origin_rank = rds.zrevrange(keys.HOT_RANK, 0, num - 1, withscores=True) # 从 Redis 中取出前 N 的原始数据 cleaned_rank = [[int(uid), int(score)] for uid, score in origin_rank] # 将原始数据中的每一项强转成int # 取出前 N 个用户 uid_list = [uid for uid, _ in cleaned_rank] # 用户的 ID 列表 users = User.objects.filter(id__in=uid_list) users = sorted(users, key=lambda user: uid_list.index(user.id)) # 整理用户数据 rank_data = [] for index, (uid, score) in enumerate(cleaned_rank): rank = index + 1 user = users[index] user_data = user.to_dict(exclude=[ 'phonenum', 'birthday', 'location', 'vip_id', 'vip_expire' ]) user_data['rank'] = rank user_data['score'] = score rank_data.append(user_data) return rank_data
def get_top_n(num): ''' 获取人气排行前 N 的用户数据 先开发,再优化,再美化 ''' origin_data = rds.zrevrange(keys.HOT_RANK_K, 0, num - 1, withscores=True) # 取出原始排行数据 cleaned = [[int(uid), int(score)] for uid, score in origin_data] # 对原始数据进行清洗 uid_list = [uid for uid, _ in cleaned] # 取出所有的 uid users = User.objects.filter(id__in=uid_list) # 取出所有用户 users = sorted(users, key=lambda user: uid_list.index(user.id)) # 调整 user 的顺序 # 组装数据 rank_data = {} for idx, user in enumerate(users): user_info = user.to_dict('phonenum', 'birthday', 'location', 'vip_id', 'vip_end') user_info['score'] = cleaned[idx][1] rank = idx + 1 rank_data[rank] = user_info return rank_data
def top_n(num): '''取出排行榜前N的用户信息''' # 从Redis中取出排行数据 rank_data = rds.zrevrange(keys.HOT_RANK_KEY, 0, num - 1, withscores=True) # 对数据进行清洗,转为int cleaned = [[int(uid), int(score)] for uid, score in rank_data] # uid_list = [item[0] for item in cleaned] # 根据用户批量提取用户,[推荐下面的推倒方式使用](取法1) uid_list = [uid for uid, _ in cleaned] users = User.objects.filter(id__in=uid_list) # in方法排行会导致原有顺序发生错乱, # 因此可以使用sorted方法根据uid_list的索引进行排序 users = sorted(users, key=lambda user: uid_list.index(user.id)) ignore_fields = [ 'phonenum', 'sex', 'birthday', 'location', 'vip_id', 'vip_expired' ] # 组装成之前设定的返回值 result = {} for idx, user in enumerate(users): score = cleaned[idx][1] u_dict = user.to_dict(*ignore_fields) u_dict['score'] = score # users的排序是根据排名而来, result[idx + 1] = u_dict return result
def get_top_n(num): # 获取热度排名 TopN 的数据 origin_data = rds.zrevrange(keys.HOT_RANK, 0, num - 1, withscores=True) cleaned = [[int(uid), int(score)] for uid, score in origin_data] #思路1: 通过for 循环低效操作 # rank_data=[] # for uid,score in cleaned: # user=User.get(id=uid) # rank_data.append([user,score]) #思路2:批量取出 一次操作 uid_list = [uid for uid, _ in cleaned] print(uid_list) users = User.objects.filter(id__in=uid_list) users = sorted(users, key=lambda user: uid_list.index(user.id)) #按照uid_list的数序排序 rank_data = [] score_list = [] for score in cleaned: score_list.append(score[1]) for user, score in zip(users, score_list): rank_data.append([user, score]) return rank_data
def get_top_n(): """ 人气排行榜功能 返回给前端的接口: { code : 0, data: [ { id:1, rank:1, score: 100, nickname: zhangsan, phonenum: xxx, xxx }, { id:2, rank: 2, score: 95, nickname: lisi, xxx }, ... ] 左滑 -5, 右滑 +5, 上滑, +7 """ # 从redis中取出排行榜数据 score_list = rds.zrevrange(config.TOP_N, 0, config.TOP_NUMBER, withscores=True) cleaned_data = [(int(uid), score) for uid, score in score_list] # 取出uid uid_list = [uid for uid, _ in cleaned_data] # 根据uid_list取到对应user users = User.objects.filter(id__in=uid_list) # # 因为queryset会自动按照model的id从小到大进行排序. # 我们需要恢复原来的顺序 users = sorted(users, key=lambda user: uid_list.index(user.id)) # 存放上榜用户的数据 data = [] for rank, (_, score), user in zip(range(1, config.TOP_NUMBER + 1), cleaned_data, users): temp = {} temp['rank'] = rank temp['score'] = score temp.update(user.to_dict()) data.append(temp) return data
def get_top_n(num): ''' 获取热度排名 Top N 的数据 Args: num: N 值 Return: rank_data = [ [<User(21)>, 52], [<User(20)>, 25], [<User(23)>, 24], ... ] ''' # origin_data = [ # (b'21', 52.0), # (b'20', 25.0), # (b'23', 24.0), # ] origin_data = rds.zrevrange(keys.HOT_RANK, 0, num - 1, withscores=True) # cleaned = [ # [21, 52], # [20, 25], # [23, 24], # ] cleaned = [[int(uid), int(score)] for uid, score in origin_data] # 思路1: 通过 for 循环操作 (低效) # rank_data = [] # for uid, score in cleaned: # user = User.get(id=uid) # rank_data.append([user, score]) # 思路2: 批量取出,一次操作 uid_list = [uid for uid, _ in cleaned] users = User.objects.filter(id__in=uid_list) # 批量取出所有用户 users = sorted(users, key=lambda user: uid_list.index(user.id)) # 按 uid_list 中的顺序排列 rank_data = [] for user, (_, score) in zip(users, cleaned): rank_data.append([user, score]) return rank_data
def get_top_n(num): '''获取TopN数据''' origin_data = rds.zrevrange(keys.SCORE_RANK, 0, num - 1, withscores=True) # 数据清洗 cleaned_data = [[int(uid), int(score)] for uid, score in origin_data] # 取出用户 uid_list = [uid for uid, _ in cleaned_data] users = User.objects.in_bulk(uid_list) #组装结果 rank_data = [] for uid, score in cleaned_data: user = users[uid] user_data = user.to_dict() rank_data.append(user_data) return rank_data
def get_top_rank(num): origin_data = rds.zrevrange('hot_rank', 0, num - 1, withscores=True) cleand_data = [[int(uid), int(score)] for uid, score in origin_data] # 单个获取 # rank_data = [{'user': User.get(pk=uid).to_dict(), 'score': score} for uid, score in cleand_data] # 批量获取 uid_list = [uid for uid, _ in cleand_data] user_list = User.objects.filter(id__in=uid_list) # 通过 sorted 进行排序,排序依据为:uid_list 的下标 user_list = sorted(user_list, key=lambda user: uid_list.index(user.id)) rank_data = [] for user, (_, score) in zip(user_list, cleand_data): rank_data.append([user, score]) return rank_data
def get_rank_list(RANK_NUM): '''从有序集合里取出前10个数据组成一个列表[(b'678', 103.0),(b'43', 100.0),..]''' data_list = rds.zrevrange(keys.HOT_RANK, 0, RANK_NUM - 1, withscores=True) cleaned_list = [(int(uid), int(score)) for uid, score in data_list] # 取出列表里的所有UID,score组成强转为int, uid_list = [uid[0] for uid in cleaned_list] # 所有UID组成列表 rank_users = User.objects.filter( id__in=uid_list) # 这一组用户是以id升序的,需要以zset里的顺序为主 sorted_users = sorted(rank_users, key=lambda user: uid_list.index(user.id)) rank_data = [] for index, (_, score) in enumerate(cleaned_list): rank = index + 1 user = sorted_users[index] user_data = user.to_dict( exclude=['phonenum', 'birthday', 'location', 'vip_id', 'vip_end']) user_data['rank'] = rank user_data['score'] = score rank_data.append(user_data) return rank_data
def get_hot_n(num): """获得积分排名 n 的数据""" origin_data = rds.zrevrange(keys.HOT_RANK_K, 0, num - 1, withscores=True) # 获得原始数据 cleaned = [[int(uid), int(score)] for uid, score in origin_data] # 原始数据清洗 uid_list = [uid for uid, _ in cleaned] # 取出所有uid users = User.objects.filter(id__in=uid_list) # 取出所有用户 users = sorted(users, key=lambda user: uid_list.index(user.id)) # 调整 user 的顺序 # 组装数据 rank_data = {} for idx, user in enumerate(users): user_info = user.to_dict('phonenum', 'birthday', 'location') user_info['score'] = cleaned[idx][1] rank = idx + 1 rank_data[rank] = user_info return rank_data
def get_top_n(num): origin_data = rds.zrevrange(keys.HOT_RANK_K, 0, num - 1, withscores=True) # 取出原始排行数据 print(origin_data) cleaned = [[int(uid), int(score)] for uid, score in origin_data] # 对原始数据进行清洗 uid_list = [uid for uid, _ in cleaned] # 取出所有的uid users = User.objects.filter(id__in=uid_list) # 取出所有的用户 users = sorted(users, key=lambda user: uid_list.index(user.id)) # 对用户进行排序 rank_data = {} for idx, user in enumerate(users): score = cleaned[idx][1] user_info = user.to_dict('email', 'birthday', 'location', 'vip_id', 'vip_end') rank = idx + 1 rank_data[rank] = user_info return rank_data
def get_top_n(num): # 取出并且清洗数据 origin_data = rds.zrevrange(keys.RANK_KEY, 0, num - 1, withscores=True) # 将取出的数据改成int类型 cleaned = [[int(uid), int(score)] for uid, score in origin_data] # 取出每一个用户 user_list = [i[0] for i in cleaned] users = User.objects.filter(id__in=user_list) # 取出的数据是按照user的id升序排列的,需要重新定义sorted方法 users = sorted(users, key=lambda user: user_list.index(user.id)) rank_data = {} # enumerate 可以返回users里面的index for idx, user in enumerate(users): # 返回user信息 user_info = user.to_dict() # 计算排名 rank = idx + 1 # 添加积分,值是cleaned里对应排名的索引为1的 user_info['score'] = cleaned[idx][1] # 添加rank,值是user_info rank_data[rank] = user_info return rank_data
def get_top_n(RANK_NUM): '''获取排行榜前 N 的用户数据''' origin_rank = rds.zrevrange(keys.HOT_RANK, 0, RANK_NUM - 1, withscores=True) # 将原始数据中的类型强转为int cleaned_rank = [[int(uid), int(score)] for uid, score in origin_rank] # 获取前 N 的uid uid_list = [uid for uid, _ in cleaned_rank] # 取出前 N 的用户 users = User.objects.filter(id__in=uid_list) users = sorted(users, key=lambda user: uid_list.index(user.id)) rank_data = [] for index, (_, score) in enumerate(cleaned_rank): rank = index + 1 user = users[index] user_data = user.to_dict(exclude=['phonenum', 'birthday', 'location', 'vip_id', 'vip_expire', ]) user_data['rank'] = rank user_data['score'] = score rank_data.append(user_data) return rank_data
def get_top_n(num): '''获取排行前 N 的用户数据''' # 数据格式 # origin_data = [ # (b'575', 920.0), # 第一项是 uid, 第二项是"用户积分" # (b'778', 624.0), # (b'632', 520.0), # ] origin_data = rds.zrevrange(keys.SWIPE_RANK, 0, num - 1, withscores=True) # 整理数据格式 cleaned_data = [[int(uid), int(score)] for uid, score in origin_data] # 生成排名数据 rank_data = {} for rank, (uid, score) in enumerate(cleaned_data, 1): user = User.get(id=uid) # NOTE: 此处可以改成批量获取,提升数据操作上的性能 user_data = user.to_dict() user_data['score'] = score rank_data[rank] = user_data return rank_data
def like_someone(uid, sid): '''喜欢某人''' # 添加滑动记录 Swiped.swiper(uid, sid, 'like') # 将sid从自己的优先推荐队列中删除 rds.lrem(keys.FIRST_CRMD_K % uid, 1, sid) # 积分 score = config.HOT_RANK_SCORE['like'] print(score) # 调整被滑动者的积分 rds.zincrby(keys.HOT_RANK_K, score, sid) print(rds.zrevrange(keys.HOT_RANK_K, 0, 49, withscores=True)) # 检查对方有没有喜欢自己(右滑或上滑过自己) if Swiped.is_liked(sid, uid): # 添加好友列表 Friend.make_friends(uid, sid) return True else: return False
def top_n(num): '''取出排行榜前 N 的用户信息''' # 从 Redis 取出排行数据 rank_data = rds.zrevrange(keys.HOT_RANK_KEY, 0, num - 1, withscores=True) # 进行简单的数据清洗 cleaned = [[int(uid), int(score)] for uid, score in rank_data] # 取出用户数据 uid_list = [uid for uid, _ in cleaned] users = User.objects.filter(id__in=uid_list) users = sorted(users, key=lambda user: uid_list.index(user.id)) # 组装返回值 result = {} ignore_fields = [ 'phonenum', 'sex', 'birthday', 'location', 'vip_id', 'vip_expired' ] for idx, user in enumerate(users): score = cleaned[idx][1] u_dict = user.to_dict(*ignore_fields) u_dict['score'] = score result[idx + 1] = u_dict return result