0

Suppose I have a relation as down below:

class Student(AbstractBaseUser):
    # It inherits AbstractBaseUser and has it's own manger
    # note: I did forget to add editable here
    id = models.UUIDField(primary_key=True, default=uuid.uuid4)
    firstname
    lastname
    ...


class Teacher(models.Model):
    id = models.UUIDField(default=uuid.uuid4, primary_key=True)
    firstname
    lastname
    email
    ...


class Meeting(models.Model):
    id = models.UUIDField(default=uuid.uuid4, primary_key=True, editable=False)
    student = models.ManyToManyField(Student)
    teacher = models.ManyToManyField(Teacher)

How should I add/set a value to field 'student' or 'teacher'. I tried to assign an object from related models to them but got an error:

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

And I tried this as well:

m = Meeting()
s = Student.objects.first() #to get a random student
m.student.add(s)

Then I get: ValueError: Cannot add "<Student: sarah@gmail.com>": instance is on database "None", value is on database "default"

I did this as well:

m = Meeting.objects.create() #It does only have two mentioned fields.
m.student.add(s)

I get this: django.db.utils.ProgrammingError: column "meeting_id" is of type bigint but expression is of type uuid LINE 1: ..._meeting" ("meeting_id", "student_id") VALUES ('c7688df9-... ^ HINT: You will need to rewrite or cast the expression.

The Mir
  • 400
  • 1
  • 8
  • 17
  • Does this answer your question? [How to add multiple objects to ManyToMany relationship at once in Django ?](https://stackoverflow.com/questions/4959499/how-to-add-multiple-objects-to-manytomany-relationship-at-once-in-django) Better yet simply have a look at the docs: https://docs.djangoproject.com/en/3.2/topics/db/examples/many_to_many/ – Abdul Aziz Barkat Jun 08 '21 at 18:14
  • @AbdulAzizBarkat I tried this an I got an error. let me update the topic. Thanks – The Mir Jun 08 '21 at 18:17
  • 1
    @TheMir: you should first *create* the `Meeting` at the database side, so `m = Meeting.objects.create()`, or `m.save()`, otherwise it has no pk, and you thus can not link students/teachers to the `Meeting`. – Willem Van Onsem Jun 08 '21 at 18:21
  • Does one (or more) of your models use an `uuid` as primary key instead of an `AutoField`? – Willem Van Onsem Jun 08 '21 at 18:30
  • @WillemVanOnsem Yes I commented below your answer. – The Mir Jun 08 '21 at 18:31

2 Answers2

4

You create a Meeting and than populate it with Teachers and Students, so:

s1 = Student.objects.create(firstname='Foo', last_name='Bar')
s2 = Student.objects.create(firstname='Qux', last_name='Qux')
t1 = Teacher.objects.create(
    firstname='Some',
    last_name='One',
    email='someone@something.com'
)

m = Meeting.objects.create()
m.student.add(s1, s2)
m.teacher.add(t1)

For more information, see the Many-to-many relationships section of the documentation.

Based on the exception you shared in the question, you created the Meeting model before you made primary keys of type UUIDField. We can fix this problem by:

  1. removing the Meeting model;
  2. run makemigrations;
  3. create a new Meeting model;
  4. run makemigrations again; and
  5. run migrate to update the database.
Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
0

First save Student objects and Teacher objects

>> student_data = {'firstname': 'John', 'last_name', 'Doe', }
>> student1 = Student.objects.create(**student_data )
>>student_data = {'firstname': 'Test', 'last_name', 'Test', }
>> student2 = Student.objects.create(**student_data )

>> teacher_data  = {'firstname': 'TeacherJohn', 'last_name': 'TeacherDoe', 'email': 'john.doe@mail.com'}
>> teacher = Teacher.objects.create(**teacher_data )

Then create a Meeting object with the other fields( other than m2m). Then add/set the m2m objects.

meeting = Meeting.objects.create(**the_model_fields_as_dict)
meeting.student.add(student1, student2)
meeting.teacher.add(teacher )
Jisson
  • 3,566
  • 8
  • 38
  • 71