Django多對多模型自定義中間媒介(through)在運行期的表現 原

使用自定義中間媒介來實現多對多關係的時候,主要的目的是在中間媒介中保存關係的特有屬性。舉個例子,比如學生與課程之間的關係就屬於多對多的,而且當學生與課程建立關係之後隨之還會產生附屬的屬性,如:成績。

如下例:

<!-- 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讓其充當另外的角色罷了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章