本文中讨论的好友列表模型设计如下:
user_id = models.ForeignKey(ChatUserInfo, to_field="chat_id", on_delete=models.DO_NOTHING, db_index=True, help_text="聊天用户id")
friend_id = models.ForeignKey(ChatUserInfo, to_field="chat_id", related_name="friend", on_delete=models.DO_NOTHING, db_index=True, help_text="聊天用户id")
user_group = models.ForeignKey(ChatGroupType, to_field="flag", on_delete=models.CASCADE, help_text="好友分组")
friend_group = models.ForeignKey(ChatGroupType, to_field="flag", related_name="friend_group", on_delete=models.CASCADE, help_text="好友分组")
user_label = models.CharField(max_length=64,help_text="备注信息")
friend_label = models.CharField(max_length=64,help_text="备注信息")
create_time = models.DateTimeField("添加好友时间", auto_now_add=True)
update_time = models.DateTimeField("更新分组时间", auto_now=True)
resource = models.ForeignKey(ChatFriendResource, to_field="origin", on_delete=models.DO_NOTHING, help_text="好友来源")
即A和B互为好友,在数据库中只会保存一条记录,这样节省磁盘空间。
对于这样的模型,当前端需要展示当前用户的好友列表时,序列化方式如下:
views.py:
def get(self, request, *args, **kwargs):
"""
聊天-好友列表
:param request:
:param args:
:param kwargs:
:return:
"""
try:
chat_id = request.query_params.get("chat_id", "")
# chat_id = request.user.user.chat_id # 添加用户认证后再使用request.user
chat_user = models.ChatUserInfo.objects.get(chat_id=int(chat_id))
except ValueError:
return Response(dict(msg="请输入用户id"), status=status.HTTP_400_BAD_REQUEST)
except models.ChatUserInfo.DoesNotExist:
return Response(dict(msg="用户不存在"), status=status.HTTP_400_BAD_REQUEST)
# 好友列表
user_friends = models.ChatFriendList.objects.filter(Q(user_id=chat_id) | Q(friend_id=chat_id))
ser = serializer.FriendSerializer(instance=user_friends, many=True, context={"chat_user": chat_user})
friends = []
for data in ser.data:
friend_dict = OrderedDict()
if data["user_id"] == int(chat_id):
friend_dict["friend_id"] = data["friend_id"]
friend_dict["friend_avatar"] = data["friend_avatar"]
if data["friend_id"] == int(chat_id):
friend_dict["friend_id"] = data["user_id"]
friend_dict["friend_avatar"] = data["user_avatar"]
friend_dict["friend_name"] = data["friend_name"]
friend_dict["friend_area"] = data["friend_area"]
friend_dict["friend_status"] = data["friend_status"]
friend_dict["friend_label"] = data["friend_label"]
friend_dict["friend_resource"] = data["friend_resource"]
friends.append(friend_dict)
logger.debug("data:%s", ser.data)
return Response(dict(msg="OK", data=friends), status=status.HTTP_200_OK)
serializer.py:
class FriendSerializer(serializers.Serializer):
"""
序列化-好友列表-好友信息 ChatFriendList
"""
# 用户id
# friend_id = serializers.SerializerMethodField(method_name="get_id")
user_id = serializers.IntegerField(source="user.chat_id")
friend_id = serializers.IntegerField(source="friend.chat_id")
# 用户昵称
friend_name = serializers.SerializerMethodField(method_name="get_name")
# 用户头像
# friend_avatar = serializers.SerializerMethodField(method_name="get_avatar")
user_avatar = serializers.ImageField(source="user.user.avatar")
friend_avatar = serializers.ImageField(source="friend.user.avatar")
# 用户地区
friend_area = serializers.SerializerMethodField(method_name="get_area")
# 用户状态
friend_status = serializers.SerializerMethodField(method_name="get_status")
# 用户备注
friend_label = serializers.SerializerMethodField(method_name="get_label")
# 用户来源
friend_resource = serializers.CharField(source="resource")
def get_id(self, obj):
"""
获取好友id
:param obj:
:return:
"""
if obj.user.chat_id == self.context['chat_user'].chat_id:
# user_id是当前用户
return obj.friend.chat_id
return obj.user.chat_id
def get_name(self, obj):
"""
获取好友昵称
:param obj:
:return:
"""
if obj.user.chat_id == self.context['chat_user'].chat_id:
# user_id是当前用户
return obj.friend.user.nickname
return obj.user.user.nickname
def get_avatar(self, obj):
"""
获取好友头像
:param obj:
:return:
"""
if obj.user.chat_id == self.context['chat_user'].chat_id:
# user_id是当前用户
return obj.friend.user.avatar
return obj.user.user.avatar
def get_area(self, obj):
"""
获取好友地区
:param obj:
:return:
"""
if obj.user.chat_id == self.context['chat_user'].chat_id:
# user_id是当前用户
return obj.friend.area
return obj.user.area
def get_status(self, obj):
"""
获取好友状态
:param obj:
:return:
"""
if obj.user.chat_id == self.context['chat_user'].chat_id:
# user_id是当前用户
return obj.friend.status
return obj.user.status
def get_label(self, obj):
"""
获取好友备注
:param obj:
:return:
"""
if obj.user.chat_id == self.context['chat_user'].chat_id:
# user_id是当前用户
return obj.friend_label
return obj.user_label
def create(self, validated_data):
pass
def update(self, instance, validated_data):
pass
上面的序列化主要使用了serializers.ImageField 和 serializers.SerializerMethodField,如有错误之处,欢迎交流指正!