建立模型
class Student(models.Model):
name = models.CharField(max_length=16, verbose_name=u'名字')
age = models.IntegerField(verbose_name=u'年龄')
class Meta:
db_table = "student"
def __str__(self):
return f"{self.id},{self.name}"
class Club(models.Model):
name = models.CharField(max_length=16)
members = models.ManyToManyField("Student")
class Meta:
db_table = "club"
def __str__(self):
return f"{self.id},{self.name}"
在命令行终端输入以下命令,在MySQ中生成数据表。
python3 manage.py makemigrations
python3 manage.py migrate
新增数据
1、首先,多对多关系表在迁移时会生成三张表,虽然我们只定义了两张表,但是由于有ManyToManyField字段存在,会使得第三张表名字为:有ManyToManyField字段的模型名_字段名(例如:club_members)。这第三张表是自动生成的,当然,我们是可以控制这第三张表,稍后会说到
新增student:
Student.objects.create(name="小张", age=19)
Student.objects.create(name="小明", age=18)
Student.objects.create(name="小铭", age=19)
Student.objects.create(name="小林", age=17)
新增club
Club.objects.create(name="跑步")
Club.objects.create(name="跳远")
Club.objects.create(name="跳高")
Club.objects.create(name="跳河")
club因为存在ManyToManyField字段,所以新增数据时,不能直接将该字段拿来使用
新增club_members:
先查询student数据
student = Student.objects.get(name="小林")
再查询club数据
club = Club.objects.get(name="跑步")
添加到关联表
club.members.add(student)
注意:add()这个方法接收的是一个对象,所以,如果要进行批量添加的话,如下:
students = Student.objects.all()
club = Club.objects.get(name="跑步")
club.members.add(*students)
查询数据
查询一个社团的全部成员
c = Club.objects.get(name="跑步")
c.members.all()/c.members.values()/c.members.values_list()
查询一个成员的全部社团
s = Student.objects.filter(id=1)
s.club_set.all()/s.club_set.values()/s.club_set.values_list() # 类名的小写+_set
更新数据
更新一个club下所有成员名字为1
b=Club.objects.get(name="ww")
b.members.update(name="1") # 返回更新条数,例如:3
删除数据
1、ManyToManyField是默认级联删除的,例如,如果要删除所有club下的某个student,那么就很简单了。
club=Club.objects.get(id=1) # 先查club
club.members.filter(name="ss").delete() # 再查student,name字段是关联的Student表的name
返回数据为:(6, {u’framework.Student’: 1, u’framework.Club_members’: 5}),表示Student表删除了一条数据,Club_members表删除了5条数据。如果没有该student,那么返回为(0, {})。从上面可以看出如果使用以上方法不仅会删除Student表中数据,还会删除Club表数据。
2、有时候我们不想删除那么多数据,例如只想删除某个club下的所有数据而不影响Student表中数据,那么可以使用如下方法:
club=Club.objects.get(id=1) # 先查要删除的那个club
club.members.clear() # 调用clear()方法删除所有关于该club的数据
3、有时候我们还想只删除某个club下的某个student数据,那么可以使用如下方法:
club=Club.objects.get(id=2) # 先查club
stu=Student.objects.get(id=2) # 再获取要删除的student
club.members.remove(stu) # 调用remove方法删除