使用自定義中間媒介來實現多對多關係的時候,主要的目的是在中間媒介中保存關係的特有屬性。舉個例子,比如學生與課程之間的關係就屬於多對多的,而且當學生與課程建立關係之後隨之還會產生附屬的屬性,如:成績。
如下例:
<!-- lang: python -->
class Student(models.Model):
name = models.CharField(max_length=5)
cources = models.ManyToManyField(Course, through='StudentCourse')
class Course(models.Model):
name = models.CharField()
class StudentCourse(models.Model):
student = models.ForeignKey(Student)
course = models.ForeignKey(Course)
score=models.FloatField()
正常的情況下,我們期望能夠通過如下方式訪問到學生的所選課程及成績:
<!-- lang: python --->
cources = Student.objects.get(id=1).cources
for c in cources:
print 'Course:%s Score:%s\n' % (c.name,c.score)
實際的表現是,會產生一個運行期錯誤:找不到score字段。
究其原因就是因爲Student.cources在運行期被Django設置爲與Cources相關的Manager而不是我們預期的與StudentCourse相關的Manager。
實現以上需求實際上也非常簡單,只對代碼稍加調整:
<!-- lang: python --->
cources = Student.objects.get(id=1).studentcourse_set
for c in cources:
print 'Course:%s Score:%s\n' % (c.name,c.score)
原因是,從StudentCourse角度,他是建立量到兩個模型(Student,Course)的多對1關係,Django在啓動時,會自動在其關聯的模型上建立"[model]_set"的屬性,就想常規的多對一關係一樣——實際上他就是常規的多對一關係,只不過Student讓其充當另外的角色罷了。