Joeyboy
Joeyboy

Reputation: 472

Unique ManyToManyField DRF

I do not want to be able to create multiple Chat objects with the same EXACT participants field.

For example:

If a chat already exists, with participants=["user1", "user2"], I do not want to be able to create a new chat objects with the same EXACT participants

Looking for something like unique=True, except for manytomanyfield.

Models:

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}"

Serializer:

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

Upvotes: 1

Views: 108

Answers (1)

ruddra
ruddra

Reputation: 52028

Probably you can try like this:

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)
   

Upvotes: 1

Related Questions