我们继续social模块的编写:
先在settings.py中注册app:social
我这里把social所有代码贴出来,
admin.py,apps.py,tests.py,views.py都没动过。
models.py中如下:
这里使用了Q用作表示“或”,
from django.db import models
# Create your models here.
from django.db.models import Q
from user.models import User
class Swiped(models.Model):
"""滑动"""
STATUS = (
('superlike', '超级喜欢'),
('like', '喜欢'),
('dislike', '不喜欢')
)
uid = models.IntegerField(verbose_name='滑动者的 UID')
sid = models.IntegerField(verbose_name='被滑动者的 UID')
status = models.CharField(max_length=8, choices=STATUS)
time = models.DateTimeField(auto_now_add=True)
@classmethod
def mark(cls, uid, sid, status):
"""标记一个滑动"""
if status in ['superlike', 'like', 'dislike']:
# 怕喜欢,不喜欢,会创建两次,需要使用update_or_create函数,官网查下
default = {'status': status}
cls.objects.update_or_create(uid, sid, default=default)
@classmethod
def is_liked(cls, uid, sid):
"""检查是否喜欢过某人"""
return cls.objects.filter(
uid=uid,
sid=sid,
status__in=['like', 'superlike']
).existes()
class Friend(models.Model):
"""好友"""
uid1 = models.IntegerField()
uid2 = models.IntegerField()
"""如果A是B的好友,uid1或者uid2都可以记录A和B,因为A和B关系是相等的"""
@classmethod
def be_friends(cls, uid1, uid2):
"""成为好友"""
uid1, uid2 = (uid1, uid2) if uid1 < uid2 else (uid2, uid1)
cls.objects.get_or_create(uid1=uid1, uid2=uid2)
@classmethod
def is_friend(cls, uid1, uid2):
condition = Q(uid1=uid1, uid2=uid2) | Q(uid2=uid1, uid1=uid2)
return cls.objects.filter(condition).exists()
@classmethod
def break_off(cls, uid1, uid2):
"""断交好友关系"""
uid1, uid2 = (uid1, uid2) if uid1 < uid2 else (uid2, uid1)
try:
cls.objects.get(uid1=uid1, uid2=uid2).delete()
except cls.DoesNotExist:
pass
@classmethod
def friends(cls, uid):
condition = Q(uid1=uid) | Q(uid2=uid)
relations = cls.objects.filter(condition) # 过滤出我的好友关系
friend_id_list = []
for r in relations:
friend_id = r.uid2 if r.uid1 == uid else r.uid1
friend_id_list.append(friend_id)
return User.objects.filter(id_in=friend_id_list)
api.py中代码如下:
from django.shortcuts import render
from lib.http import render_json
from social import logic
def get_users(request):
"""获取推荐列表"""
group_num = int(request.GET.get('group_num', 0))
start = group_num * 5
end = start + 5
users = logic.get_rcmd_users(request.user)[start:end]
result = [user.to_dict() for user in users]
return render_json(result)
def like(request):
"""喜欢"""
sid = int(request.POST.get('sid'))
is_matched = logic.like(request.user, sid) # 是否完成匹配
return render_json({'is_matched': is_matched})
"""
用户每次划过一个用户,
检测一下你划过的人是否给你完成匹配,
客户端根据匹配的值提醒用户你划过的人正好也匹配过你
"""
def superlike(request):
"""超级喜欢"""
sid = int(request.POST.get('sid'))
is_matched = logic.superlike(request.user, sid) # 是否完成匹配
return render_json({'is_matched': is_matched})
def dislike(request):
"""不喜欢"""
sid = int(request.POST.get('sid'))
logic.dislike(request.user, sid) # 这里不匹配,直接返回None
return render_json(None)
def rewind(request):
"""反悔"""
sid = int(request.POST.get('sid'))
logic.rewind(request.user, sid) #
return render_json()
def friends(request):
"""好友列表"""
my_friends = Friend.friends(request.user.id)
friends_info = [frd.to_dict() for frd in my_friends]
return render_json({'friends': friends_info})
logic.py逻辑代码如下:
import datetime
from user.models import User
from social.models import Swiped, Friend
def get_rcmd_users(user):
"""
获取推荐用户
max_year min_year current_year 2020
------\------------\----------------\-------------\----->
"""
sex = user.profile.dating_sex
location = user.profile.location
min_age = user.profile.min_dating_age
max_age = user.profile.max_dating_age
current_year = datetime.date.today().year
min_year = current_year - min_age # 年份
max_year = current_year - max_age
users = User.objects.filter(sex=sex, location=location,
birth_year__gte=max_year,
birth_year__lte=min_year)
return users
def like(user, sid):
"""喜欢一个用户"""
Swiped.mark(user.id, sid, 'like')
# 检查被滑动的用户是否喜欢过自己
if Swiped.is_liked(sid, user.id):
Friend.be_friends(user.id, sid)
return True
else:
return False
def superlike(user, sid):
"""超级喜欢一个用户,和like一样"""
Swiped.mark(user.id, sid, 'superlike')
# 检查被滑动的用户是否喜欢过自己
if Swiped.is_liked(sid, user.id):
Friend.be_friends(user.id, sid)
return True
else:
return False
def dislike(user, sid):
"""不喜欢,不做处理"""
Swiped.mark(user.id, sid, 'dislike')
def rewind(user, sid):
"""反悔"""
try:
Swiped.objects.get(uid=user.id, sid=sid).delete() #直接删除
except Swiped.DoesNotExist:
pass
# 撤销好友关系
Friend.break_off(user.id, sid)