TypeError: Direct assignment to the forward side of a many-to-many set is prohibited. Use meeting.set() instead. Error with Django m2m fields

Viewed 3820

I am a beginner in Django and I am stuck with the many-to-many relationship. Here I am fetching the google meet data from my Google calendar through the calendar API. I have successfully fetched the data but when I save the participants of the meeting, I get this error:

TypeError: Direct assignment to the forward side of a many-to-many set is prohibited. Use meeting.set() instead.

This is the code with the problem:

create a partcipant object & save it
  for email in participants_emails:
    participant_obj,created = Participant.objects.create(
                meeting=meeting_obj, email=participants_emails) 
    print(f'participant {participant_obj} was created==== ',created)

In this code, I have access to all emails of participants in the participants_emails, and I was to save them in the model.

Here below is the models.py:

from django.db import models
from django.contrib.auth.models import User 

class Meeting(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    unique_key = models.CharField(max_length=100, unique=True)
    subject = models.CharField(max_length=400, null=True, blank=True)
    start_at = models.DateTimeField(
        auto_now_add=False, auto_now=False, null=True)
    end_at = models.DateTimeField(
        auto_now_add=False, auto_now=False, null=True)
    feedback_status = models.BooleanField(null=True, default=False)

    def __str__(self):
        return self.subject

class Participant(models.Model):
    meeting = models.ManyToManyField(to=Meeting)
    email = models.EmailField(default=None, blank=True, null=True)

    def __str__(self):
        return self.email

class Question(models.Model):
    question_type = [
        ('checkbox', 'CheckBox'),
        ('intvalue', 'Integar Value'),
        ('text', 'Text'),
        ('radio', 'Radio Button'),
    ]
    question_label = models.TextField(null=True, blank=True)
    question_type = models.CharField(
        choices=question_type, default='text', max_length=80)

    def __str__(self):
        return self.question_label

class UserFeedback(models.Model):
    meeting = models.ForeignKey(Meeting, on_delete=models.CASCADE)
    participant = models.ForeignKey(Participant, on_delete=models.CASCADE)
    question = models.OneToOneField(Question, on_delete=models.CASCADE)
    question_answer = models.CharField(max_length=300, null=True, blank=True)

    def __str__(self):
        return str(self.meeting)
1 Answers

You can not use meeting=meeting_obj, since this is a ManyToManyField, and in order to add something to a ManyToManyField, first both objects need to have a primary key.

You can later add it to the ManyToManyField, for example with:

for email in participants_emails:
    participant_obj, created = Participant.objects.get_or_create(email=participants_emails) 
    participant_obj.meeting.add(meeting_obj)
    print(f'participant {participant_obj} was created==== ',created)

Likely you also want to use get_or_create(…) [Django-doc] since create(…) [Django-doc] does not return a 2-tuple with created.

Related