NSP
NSP

Reputation: 1243

Link ManyToManyFields in django

I have models defined as below:

class Subject(models.Model):
    subject_id = models.IntegerField(primary_key=True)
    subject_name = models.CharField(max_length=20)

class Teacher(models.Model):
    teacher_id = models.CharField(max_length=10, primary_key=True)
    teacher_name = models.CharField(max_length=30)
    teacher_age = models.IntegerField()
    teacher_doj = models.DateField()
    subjects = models.ManyToManyField(Subject)

class TeacherScores(models.Model):
    co_id = models.CharField(primary_key = True, max_length=5)
    internal_score = models.IntegerField()
    external_score = models.IntegerField()
    teacher = models.ManyToManyField(Teacher)

Few DB entries are shown below

Teacher

+------------+--------------+-------------+-------------+
| teacher_id | teacher_name | teacher_age | teacher_doj |
+------------+--------------+-------------+-------------+
| AC23001    | Tina         |          32 | 2017-04-10  |
| AC23002    | Rina         |          31 | 2009-04-10  |
| AC23003    | Tom          |          35 | 2009-04-10  |
| AC23004    | Henry        |          56 | 2009-04-10  |
+------------+--------------+-------------+-------------+

Subjects

+------------+--------------+
| subject_id | subject_name |
+------------+--------------+
|          1 | English      |
|          2 | Hindi        |
|          3 | Sanskrit     |
|          4 | Math         |
|          5 | Physics      |
|          6 | Chemistry    |
|          7 | Biology      |
|          8 | History      |
|          9 | Civics       |
|         10 | Geography    |
|         11 | MoralScience |
|         12 | Algebra      |
+------------+--------------+

teacher_subject

+----+------------+------------+
| id | teacher_id | subject_id |
+----+------------+------------+
|  4 | AC23002    |          4 |
|  5 | AC23002    |          8 |
|  2 | AC23002    |         12 |
|  6 | AC23003    |          5 |
|  7 | AC23003    |          9 |
| 10 | AC23004    |          5 |
|  8 | AC23005    |          9 |
|  9 | AC23005    |         10 |
| 11 | AC23006    |         12 |
| 12 | AC23007    |          6 |
| 13 | AC23008    |          6 |
+----+------------+------------+

Basically I want to add entries to the TeacherSCores model for a particular teacher per subject that he/she handles. Here I want to modify the TeacherScores model such that I can include scores for a teacher per subject. I tried inserting subjects via the teacherscores object but I get error.

>>> t1 =  TeacherScores('C006','23','24',teacher__subject='Math')
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/usr/local/lib/python2.7/dist-packages/Django-1.11.5-py2.7.egg/django/db/models/base.py", line 572, in __init__
    raise TypeError("'%s' is an invalid keyword argument for this function" % list(kwargs)[0])
TypeError: 'teacher__subject' is an invalid keyword argument for this function
>>> t1 =  TeacherScores('C006','23','24',teacher__subjects='Math')
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/usr/local/lib/python2.7/dist-packages/Django-1.11.5-py2.7.egg/django/db/models/base.py", line 572, in __init__
    raise TypeError("'%s' is an invalid keyword argument for this function" % list(kwargs)[0])
TypeError: 'teacher__subjects' is an invalid keyword argument for this function

How can change my Model- TeacherScores to include the subject field for a teacher provided there is a ManyToMany field defined between teacher and subject, also with TeacherScores and Teacher

Upvotes: 1

Views: 359

Answers (1)

Siegmeyer
Siegmeyer

Reputation: 4512

What you want to do is to create explicit TeacherSubject class used to model M2M relationship between Teacher and Subject. Then you can reference it in TeacherScores.

1. Model M2M Teacher-Subject relation using through option:

class TeacherSubject(models.Model):
    teacher = models.ForeignKey(Teacher, on_delete=models.CASCADE)
    subject = models.ForeignKey(Subject, on_delete=models.CASCADE)
    # extra fields ...

and then modify Teacher and TeacherScores to use TeacherSubject:

# Teacher:

subjects = models.ManyToManyField(Subject, through=TeacherSubject)

# TeacherScores:

teachersubject = models.ForeignKey(TeacherSubject)

2. Explicitly reference TeacherSubject:

t1 =  TeacherScores('C006','23','24', teachersubject=some_teachersubject_instance)

Details are described here.

Upvotes: 2

Related Questions