独特的多对多字段 DRF

Unique ManyToManyField DRF

我不希望能够使用完全相同的参与者字段创建多个聊天对象。

例如:

如果聊天已经存在,participants=["user1", "user2"], 我不希望能够创建具有完全相同参与者的新聊天对象

寻找类似 unique=True 的东西,除了 manytomanyfield。

型号:

class Contact(models.Model):
    user = models.ForeignKey(
        User, related_name='friends', on_delete=models.CASCADE)
    friends = models.ManyToManyField('self', blank=True)

    def __str__(self):
        return self.user.username


class Message(models.Model):
    contact = models.ForeignKey(
        Contact, related_name="messages", on_delete=models.CASCADE)
    content = models.TextField()
    timestamp = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.contact.user.username


class Chat(models.Model):

    participants = models.ManyToManyField(
        Contact, related_name='chats')
    messages = models.ManyToManyField(Message, blank=True)

    def __str__(self):
        return f"{self.pk}"

序列化器:

class ContactSerializer(serializers.StringRelatedField):
    def to_internal_value(self, value):
        return value


class ChatSerializer(serializers.ModelSerializer):
    participants = ContactSerializer(many=True)

    class Meta:
        model = Chat
        fields = ("id", "messages", "participants")
        read_only = ('id')

    def create(self, validated_data):
        print(validated_data)
        participants = validated_data.pop('participants')

        # for c in Chat.participant_set.all():
        #    print(c)

        chat = Chat()
        chat.save()
        for username in participants:
            contact = get_user_contact(username)
            chat.participants.add(contact)
        chat.save()
        return chat

或许你可以这样尝试:

participants = validated_data.pop('participants')    
prev_chat = Chat.objects.all()
for username in participants:
   prev_chat = prev_chat.filter(participants__username=username)

if prev_chat.exists():
    chat = prev_chat.first()
else:
   chat = Chat()
   chat.save()
   for username in participants:
     contact = get_user_contact(username)
     chat.participants.add(contact)