Search code examples
pythondjangomanytomanyfielddjango-shell

How do I fill in nested ManyToMany fields in Django with Shell?


Have checked the questions on this topic on SO, of them many are outdated (dj<=1.4), so asking a new quesiton. I guess this is simple, I'm much beginner with Django and Python.

I have some models, of which there are nested ManyToManyFields, I want to know, how can I save an object on the lower level while including all the top levels. That is just by adding the teacher object I want to add students and parents on the same fly.

My models

class Parent(models.Model):
    name = models.CharField(max_length=10)
    address = models.TextField(blank=True)

class Student(models.Model):
    name = models.CharField(models.Model)
    parents = models.ManyToManyField(Parent)

class Teacher(models.Model):
    name = models.CharField(max_length=10)
    student = models.ManyToManyField(Student)

I know to create an object to a simple model, by Teacher.objects.create(name='some name') but don't know how to fill the student and parents.

sample data

teacher: Susan

students: Alan, Mike

parents: Alan-> George, Mike-> John Doe (address be blank)

Thanks for any help.

pS. please don't say its impossible as it is possible through admin panel (GUI)


Solution

  • To create and associate Student and Parent objects using Teacher object, you can use .create() along with .add().

    For example:

    teacher =  Teacher.objects.create(name='some name')
    student = Student.objects.create(name='some_name')
    parent =  Parent.objects.create(name='some_name', address='some_address')
    

    This will create a teacher, student and parent object.

    Then to associate them, you can do something like:

    teacher.student.add(student) # associate the 'teacher' object with the  'student' object 
    
    student.parents.add(parent) # associate the 'student' object with the 'parent' object
    

    For your case, you can do something like:

    teacher = Teacher.objects.create(name='Susan') # create a teacher object
    student1 = Student.objects.create(name='Alan') # create 1st student
    student2 = Student.objects.create(name='Mike') # create 2nd student
    parent1 = Parent.objects.create(name='George') # create parent object
    parent2 = Parent.objects.create(name='John Doe') # create parent object
    
    teacher.student.add(student1) # associate teacher with 1st student
    teacher.student.add(student2) # associate teacher with 2nd student
    
    student1.parents.add(parent1) # associate 1st student with parent1
    student2.parents.add(parent2) # associate 2nd student with parent2
    

    Note: It would be better if you define student field in Teacher model as students instead of student i.e. use plural form.