2013-12-12 37 views
1

我有兩個模型是老師和學生。我還有另外兩個模型,一堂課和一堂課,其中課程是實際的課題,而課堂則用來劃分學生。我想創建以下關係。使用ManyToManyField並確保DatabaseIntegrity

A teacher teaches a specific lesson in a specific class e.g Mike teaches python in C3 

A student attends a class with a specific lesson e.g George is taking Python in C3 

所以eventualy

George is Mike's student in python in C3 

我用使用中間模型在兩個模型中一個多對多字段。很多很多,因爲老師可以有很多類,在那裏他可以教很多教訓,一類可能有許多教師的教學不同的經驗教訓(同爲學生)

,所以我做了以下內容:

class Teacher(models.Model): 
    teaches = models.ManyToManyField(Class, through=TeacherTeaches) 

class TeacherTeaches(models.Model): 
    teacher = models.ForeignKey(Teacher) 
    class = models.ForeignKey(Class) 
    lesson = models.ForeignKey(Lesson) 

和學生:

class Student(models.Model): 
    attends = models.ManyToManyField(Class, through=StudentAttends) 


class StudentAttends(models.Model): 
    student = models.ForeignKey(Student) 
    class = models.ForeignKey(Class) 
    lesson = models.ForeignKey(Lesson) 

但我認爲它不能與這個實現做的是確保了同樣的問題不是由兩個不同的教師,正確在同一類教因爲ForeignKey的的(?我認爲)。有沒有更好的方法來「建立」我的模型來實現上述行爲?我應該「團結」兩種中間模式嗎?

回答

2

也許你需要從另一個方向接近它來限制多對多的關係。 A類(或房間,因爲你不能使用關鍵字class作爲標識符)只能有一個教訓,一個老師,所以:

class Room(Model): 
    teacher = ForeignKey(Teacher) 
    lesson = ForeignKey(Lesson) 

老師可以教多的教訓,但只在一個房間裏,所以這已經可以從Room型號查詢,如:

Teacher.objects.select_related().values('lesson') 

學生可以有多個課,客房和教師,所以沒有辦法避免許多一對多的關係,但教訓,教師已經與房間相關,因此與房間創建多對多將是最簡單的方式。這可以從兩側進行,因此模型變爲:

class Room(Model): 
    teacher = ForeignKey(Teacher) 
    lesson = ForeignKey(Lesson) 
    students = ManyToManyField(Student) 

現在,確保教師和教訓是獨特的很簡單,只要加入相應的約束:

class Room(Model): 
    teacher = ForeignKey(Teacher) 
    lesson = ForeignKey(Lesson) 
    students = ManyToManyField(Student) 

    class Meta: 
     unique_together = ('teacher', 'lesson')