• Index

django 多对多关系

Reads: 990 Edit

建立模型

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方法删除

Comments

Make a comment

www.ultrapower.com ,王硕的博客,专注于研究互联网产品和技术,提供中文精品教程。 本网站与其它任何公司及/或商标无任何形式关联或合作。
  • Index
aaaaa