如何在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
相关产品推荐
相关产品推荐

