You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Django REST Framework中为用户实现联系人功能

解决方案建议

方案一:使用ManyToManyField(最简实现)

这是实现通讯录功能最直接的方式,适合不需要额外关联信息的简单场景。直接在IndividualUser模型中添加关联自身的多对多字段即可。

修改后的models.py代码:

from django.db import models
from django.utils.translation import gettext_lazy as _
from django.contrib.auth.models import User

class IndividualUser(models.Model):
    individual_user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
    first_name = models.CharField(_("first name"), max_length=150)
    last_name = models.CharField(_("last name"), max_length=150)
    # 新增联系人关联字段
    contacts = models.ManyToManyField('self', symmetrical=False, related_name='contact_of', blank=True)
  • symmetrical=False:确保A添加B为联系人时,不会自动双向关联,符合通讯录单向添加的逻辑
  • related_name='contact_of':方便反向查询,比如查看哪些用户将当前用户添加为联系人

DRF序列化器示例:

from rest_framework import serializers
from .models import IndividualUser

class IndividualUserSerializer(serializers.ModelSerializer):
    class Meta:
        model = IndividualUser
        fields = ['individual_user', 'first_name', 'last_name', 'contacts']

方案二:自定义中间表(支持扩展需求)

如果后续需要给联系人添加备注名、分组、添加时间等额外信息,建议使用自定义中间表,通过through参数关联。

修改后的models.py代码:

from django.db import models
from django.utils.translation import gettext_lazy as _
from django.contrib.auth.models import User

class ContactRelationship(models.Model):
    from_user = models.ForeignKey(IndividualUser, on_delete=models.CASCADE, related_name='contact_relationships')
    to_user = models.ForeignKey(IndividualUser, on_delete=models.CASCADE, related_name='related_contacts')
    note_name = models.CharField(_("备注名"), max_length=150, blank=True)
    group = models.CharField(_("分组"), max_length=100, blank=True)
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        unique_together = ('from_user', 'to_user')  # 避免重复添加同一联系人

class IndividualUser(models.Model):
    individual_user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
    first_name = models.CharField(_("first name"), max_length=150)
    last_name = models.CharField(_("last name"), max_length=150)
    contacts = models.ManyToManyField('self', through=ContactRelationship, symmetrical=False, related_name='contact_of', blank=True)

对应的DRF序列化器示例:

from rest_framework import serializers
from .models import IndividualUser, ContactRelationship

class ContactRelationshipSerializer(serializers.ModelSerializer):
    to_user = serializers.PrimaryKeyRelatedField(queryset=IndividualUser.objects.all())

    class Meta:
        model = ContactRelationship
        fields = ['to_user', 'note_name', 'group', 'created_at']

class IndividualUserSerializer(serializers.ModelSerializer):
    contacts = ContactRelationshipSerializer(source='contact_relationships', many=True)

    class Meta:
        model = IndividualUser
        fields = ['individual_user', 'first_name', 'last_name', 'contacts']

方案选择参考

  • 仅需基础的“添加联系人”功能,无额外信息需求:优先选方案一,代码简洁易维护
  • 需要备注、分组等扩展功能:直接采用方案二,避免后期重构成本

内容的提问来源于stack exchange,提问作者Zesshi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 02:05:05