django创建多对多表三种方法,和ORM操作增删改查

  • 不管是哪种方法,都能完成你需要的操作,只不过方式不同。根据自己的需要选择一种就行了。

第一种:自带的ManyToManyField

django会帮你在数据库自动生成一个老师和班级的关系表,但不显示在models.py里面,所以不能直接操作关系表,但是可以间接操作。

  • 不足之处:关系表只能有三个字段,比如我想在关系表中添加一个上课时间的字段,那么就不能用此方法。
class teacher(models.Model):
    t_name = models.CharField(max_length=20,default="0")
    tea_cla = models.ManyToManyField(to='class')

class classes(models.Model):
    c_name = models.CharField(max_length=20,default="0")
  1. add()方法
    给AAA老师增加一门课,id为3:
obj = models.teacher.objects.get(t_name = 'AAA')
obj.tea_cla.add(3)

add(1)或add(2,3)或列表add(*[1,2])

  1. remove()方法
    AAA老师不上某课了
obj.tea_cla.remove()#用法同add()
  1. 改(重置) set()方法
    重新决定AAA老师上哪几门课
obj.tea_cla.set([列表类型])
  1. all()和filter()
    查询AAA老师上哪几门课
q = obj.tea_cla.all()
#q是AAA老师教的所有班级的对象
#也可以进一步筛选,查询AAA老师教的线代
w = obj.tea_cla.filter(c_name = '线代')
  • 清空 clear()
    将AAA老师的课清空
obj.tea_cla.clear()

反向查询,通过课程查老师 _set

  • 方法与上面一样,只是方向不同,注意_set

查询教线代的老师有哪些

class_obj = models.classes.objects.get(c_name = '线代')
v = class_obj.teacher_set.all()

第二种:自己写关系表

  • 注意get()和filter()的区别,filter返回对象的列表,get返回一个对象,当有多个返回值会报错。
class teacher(models.Model):
    t_name = models.CharField(max_length=20,default="0")

class classes(models.Model):
    c_name = models.CharField(max_length=20,default="0")

class tea_cla(models.Model):
    t = models.ForeignKey(to='teacher',on_delete=models.CASCADE)
    c = models.ForeignKey(to='classes',on_delete=models.CASCADE)
  • 增加删除修改就不说了,跟单表操作差不多,注意下外键约束即可。

  • 查询
    1.两次外键连表查询
    for循环里面操作数据库,性能不高

#获取AAA老师的对象
obj = models.teacher.objects.get(t_name = 'AAA')
#获取关系表所有AAA老师教的课的对象
class_list = obj.tea_cla_set.all()
#再来个循环就能拿到
for item in class_list:
	print(item.c.c_name)

2.以关系表为核心查询
注意双下划线的用法

#获取关系表中AAA老师相关对象
class_list = models.tea_cla.objects.filter(t__t_name = 'AAA')
##再来个循环就能拿到
for item in class_list:
	print(item.c.c_name)

3.字典或列表(合并两次跨表)

class_list = models.tea_cla.objects.filter(t__t_name = 'AAA').values('c__c_name')
#字典类型,列表就用valueslist
for item in class_list:
	print(item['c__c_name'])

4.对象(与3差不多)

class_list = models.tea_cla.objects.filter(t__t_name = 'AAA').select_related('c')
#对象类型
for obj in class_list:
	print(obj.c.c_name)

第三种:两者结合

既自己写关系表,又使用ManyToManyField

class teacher(models.Model):
    t_name = models.CharField(max_length=20,default="0")
    z = models.ManyToManyField(to='classes',through='tea_cla',through_fields=('t,c'))

class classes(models.Model):
    c_name = models.CharField(max_length=20,default="0")

class tea_cla(models.Model):
    t = models.ForeignKey(to='teacher',on_delete=models.CASCADE)
    c = models.ForeignKey(to='classes',on_delete=models.CASCADE)

through和through_fields:表示通过tea_cla表的t和c两个字段

  • 操作方法是前两种的总和
  • add() remove() set() 无法使用
  • clear() all() 可以使用
原创文章 7 获赞 7 访问量 919

猜你喜欢

转载自blog.csdn.net/weixin_43159092/article/details/105746294