假设有表的关系如下:
class Classes(models.Model):
name = models.CharField(max_length=32)
institute = models.CharField(max_length=32)
headteacher = models.ForeignKey("Teacher")
def __str__(self):
return self.name
class Teacher(models.Model):
name = models.CharField(max_length=32)
student_belong = models.ManyToManyField("Students")
def __str__(self):
return self.name
class Students(models.Model):
name = models.CharField(max_length=32)
class_belong = models.ForeignKey("Classes")
def __str__(self):
return self.name
简单来说,就是老师和班级是一对多,和学生是多对多。
一对多
class_all = Classes.objects.all() class_one = Classes.objects.get(id=1)
得到了两个对象,假设班级中有headteacher这样的查询为正向的查询。
那么正向:
tea = class_one.headteacher.name all_class = class_all.values_list("id","name","headteacher__name")
tea是通过点的方式直接找到了相关联的老师信息。通过values这种方式则是要用双下划綫__。一般直接使用values结果是字典形式。
反向:指的是teacher是被关联方里面没有class字段。
teacher_one = Teacher.objects.get(id=1)
teacher_all = Teacher.objects.all()
all_class = teacher_all.values("name","classes__name") 这里class必须是小写。
class_name = teacher_one.classes_set
反向的values里面在写错的时候会报错并提示有几个可选。得知有classes选项。虽然在models的Teacher类中没有这个字段。
在使用点的时候也有所不同多出了下划线_set的用法。
多对多
有django自动生成多对多表的操作 (也可以自己写)
author_list = models.Author.objects.values("id","name","m__name") # values 中直接写关系 双下划綫是表示m的name
print(author_list)
obj = models.Author.objects.get(id=1)
增加
obj.m.add(3)
obj.m.add(3,4)
obj.m.add(*[2,3])
删除
obj.m.remove(3)
obj.m.remove(3,4)
obj.m.remove(*[2,3])
修改
obj.m.set([1,2,3]) # 有则覆盖 无则增加
obj.m.clear()
反向
obj = models.Book.objects.get(id=2)
obj_author = obj.author_set # 拿到作者列表增删改查一样
自己写的多对多关系表
class T_S(models.Model):
teacher_id = models.ForeignKey(Teacher)
student_id = models.ForeignKey(Student)
class Meta():
unique_together = (
('teacher_id','student_id'),
)
其中meta是将这两个变成联合唯一。防止重复出现。
自己写第三张关系表的优点在于所有的一对多的操作都可以用在多对多的表中。利于查询等操作。