实战Django之Model操作之多对多(ManyToMany)正反调用

目录篇:Django之model操作ORM目录篇 点击跳转
主篇:Django之Model操作之多对多(ManyToMany)正反调用【ORM篇六】点击跳转

目录

  • ManyToMany(Django提供的三种多对多方式)
  •     1.自动创建多对多关联(django自动维护第三张表)
  •         建立表类
  •         表数据(django自带的sqlite可视化进行添加,当然也可以进行命令添加)
  •         根据类表进行django的shell命令行操作外键正反调用
  •     2.手动创建多对多关联(手动维护第三章表)
  •         建立表类
  •         表数据(django自带的sqlite可视化进行添加,当然也可以进行命令添加)
  •         根据类表进行django的shell命令行操作外键正反调用
  •     3.自动+手动(手动维护第三章表)
  •         建立表类
  •         表数据(django自带的sqlite可视化进行添加,当然也可以进行命令添加)
  •         根据类表进行django的shell命令行操作外键正反调用

ManyToMany(Django提供的三种多对多方式)

而django的多对多有3种方式可以选择
1.通过m2m字段自动创建了第三张表(django自动维护第三张表)
2.创建第三张表(需要手动维护该表)
3.通过m2m字段指定手动表(需要手动维护该表)

注意:
1.根据多对多字段进行系统自动生成的第三张表,admin会帮你生成下拉框,系统自动维护第三张表(根据django提供的格式进行操作第3战表)
2.手动创建第三张表,admin是不会生成下拉框的,自己维护第三张表(第3张表进行手动操作)
3.自动+手动,admin是不会生成下拉框,自己维护第三张表(第3张表进行手动操作,django提供格式只允许查和清除功能)

 

    1.自动创建多对多关联(django自动维护第三张表)

        建立表类

跳转:实战之Django之Model建表流程 https://blog.csdn.net/Burgess_zheng/article/details/86564984

路径:project/modes_handle/models.py

from django.db import models
class A(models.Model):
    name = models.CharField(max_length=10)
class B(models.Model):
    name = models.CharField(max_length=10)
    m2m = models.ManyToManyField("A",related_name='bn')

进入项目目录下执行以下面命令(创建表 or 重新生成表结构)
python manage.py makemigrations
python manage.py migrate

        表数据(django自带的sqlite可视化进行添加,当然也可以进行命令添加)

A表

实战Django之Model操作之多对多(ManyToMany)正反调用_第1张图片

B表

实战Django之Model操作之多对多(ManyToMany)正反调用_第2张图片

M2M表

实战Django之Model操作之多对多(ManyToMany)正反调用_第3张图片

        根据类表进行django的shell命令行操作外键正反调用

进入项目目录(执行如下命令进行django提供的shell命令行)

F:\Burgess\Python\pycharm实验脚本\test\project_burgess>python manage.py shell

获取B表指定数据对象的所有关联的A表数据(正向调用)

>>> from modes_handle import models
>>> A_obj = models.A.objects.first()
>>> B_obj = models.B.objects.first()
>>> A_obj.name
'红1'
>>> B_obj.name
'强1'
>>> for obj in B_obj.m2m.all():
...     print(obj.name)
...
红1
红2

  #Django创建的多对多表增删改查(正向操作)

A_obj = models.A.objects.first()  #数据对象(A表第一行数据)
B_obj = models.B.objects.first()  #数据对象(B表第一行数据)
B_obj.m2m.add(1)      #B_obj对象本身进行关联A表的指定id数据(第三张表自动维护增加)
B_obj.m2m.add(2,3,4)   #B_obj对象本身进行关联A表的N个指定id数据(第三张表自动维护增加)
B_obj.m2m.add(*[2,3,4]) #B_obj对象本身进行关联A表的N个指定id数据(第三张表自动维护增加)
B_obj.m2m.remove(1)   #移除该B_obj对象所关联的A表的指定id数据(第三张表自动维护移除)
B_obj.m2m.remove(2,3)  #移除该B_obj对象所关联的A表的N个指定id数据(第三张表自动维护移除)
B_obj.m2m.remove(*[2,3]) #移除该B_obj对象所关联的A表的N个指定id数据(第三张表自动维护移除)
B_obj.m2m.clear(*[2,3])   #清除掉该B_obj对象所有关联A表的id数据(第三张表自动维护移除)
B_obj.m2m.set(*[2,3])    #重置该B_obj对象的关联的A表指定N个id数据(第三张表自动维护重置)
A_obj.m2m.all()          #查看该B_obj对象所关联的A表的所有数据
A_obj.m2m.filter(xx='xx')   #查看该B_obj对象所关联的A表的指定数据

获取A表指定数据对象的所有关联的B表数据(反向调用)

>>> from modes_handle import models
>>> A_obj = models.A.objects.first()
>>> B_obj = models.B.objects.first()
>>> A_obj.name
'红1'
>>> B_obj.name
'强1'
>>> for obj in A_obj.bn.all():
...     obj.name
...
'强1'
'强2'
插入:如果数据表创建的时候多对多字段没有设置related_name参数(“多对多表名小写“ + “_set“))
>>> for obj in A_obj.b_set.all():
...     obj.name
...
'强1'
'强2'

  Django创建的多对多表增删改查(反向操作)

A_obj = models.A.objects.first()  #数据对象(A表第一行数据)
A_obj.bn.add(1)      #A_obj对象本身进行关联B表的指定id数据(第三张表自动维护增加)
A_obj.bn.add(2,3,4)   #A_obj对象本身进行关联B表的N个指定id数据(第三张表自动维护增加)
A_obj.bn.add(*[2,3,4]) #A_obj对象本身进行关联B表的N个指定id数据(第三张表自动维护增加)
A_obj.bn.remove(1)   #移除该A_obj对象所关联的B表的指定id数据(第三张表自动维护移除)
A_obj.bn.remove(2,3)  #移除该A_obj对象所关联的B表的N个指定id数据(第三张表自动维护移除)
A_obj.bn.remove(*[2,3]) #移除该A_obj对象所关联的B表的N个指定id数据(第三张表自动维护移除)
A_obj.bn.clear(*[2,3])   #清除掉该A_obj对象所有关联B表的id数据(第三张表自动维护移除)
A_obj.bn.set(*[2,3])    #重置该A_obj对象的关联的B表指定N个id数据(第三张表自动维护重置)
A_obj.bn.all()          #查看该A_obj对象所关联的B表的N个数据
A_obj.bn.filter(xx=xx)   #查看该A_obj数据所关联的B表的指定数据

 

    2.手动创建多对多关联(手动维护第三章表)

        建立表类

跳转:实战之Django之Model建表流程 https://blog.csdn.net/Burgess_zheng/article/details/86564984

路径:project/modes_handle/models.py

from django.db import models
class A(models.Model):
    name = models.CharField(max_length=10)
class B(models.Model):
    name = models.CharField(max_length=10)
class M2M(models.Model):
    a_obj = models.ForeignKey("A",related_name="an",on_delete=None)
    b_obj = models.ForeignKey("B",related_name="bn",on_delete=None)

进入项目目录下执行以下面命令(创建表 or 重新生成表结构)
python manage.py makemigrations
python manage.py migrate

        表数据(django自带的sqlite可视化进行添加,当然也可以进行命令添加)

A表

实战Django之Model操作之多对多(ManyToMany)正反调用_第4张图片

B表

实战Django之Model操作之多对多(ManyToMany)正反调用_第5张图片

M2M表

实战Django之Model操作之多对多(ManyToMany)正反调用_第6张图片

        根据类表进行django的shell命令行操作外键正反调用

进入项目目录(执行如下命令进行django提供的shell命令行)

F:\Burgess\Python\pycharm实验脚本\test\project_burgess>python manage.py shell

获取A表指定数据对象的所有关联的B表数据

    方式1(通过多对多字段设置的related_name进行反向调用)

>>> from modes_handle import models
>>> A_obj = models.A.objects.first()
>>> B_obj = models.B.objects.first()
>>> m2m_obj= models.M2M.objects
>>> A_obj.name
'红1'
>>> B_obj.name
'强1'
>>> for m2m_obj in A_obj.an.all():
...     m2m_obj.b_obj.name
...
'强1'
'强2'

插入:(如果数据表创建时候没有使用related_name参数(”多对多表名小写” + “_set”)
>>> for m2m_obj in A_obj.m2m_set.all():
...     m2m_obj.b_obj.name
...
'强1'
'强2'

    方式2(通过M2M表字段,字段值,字段双下划线+关联表字段进行匹配指定A_obj对象的对应信息,最终得到了该A_obj对象所关联B_obj对象的m2m本表对象,然后通过该m2m对象调用自身关联B表的外键字段)

>>> A_obj = models.A.objects.filter(id=1).first()
>>> m2m_obj=models.M2M.objects.filter(a_obj=A_obj)
>>> m2m_obj=models.M2M.objects.filter(a_obj__id=A_obj.id)
>>> m2m_obj=models.M2M.objects.filter(a_obj__name=A_obj.name)
>>>
>>> m2m_obj
, ]>
>>> for m2m_obj in m2m_obj:
...     m2m_obj.b_obj.name
...
'强1'
'强2'

    方式3(通过多对多字段设置的related_name进行反向调用)

>>> A_obj = models.A.objects.filter(id=1).first()
>>> b_list_obj=models.B.objects.filter(bn__a_obj=A_obj)
>>> b_list_obj=models.B.objects.filter(bn__a_obj_id=A_obj.id)
>>> for obj in b_list_obj:
...     obj.name
...
'强1'
'强2'
插入:(如果数据表创建时候没有使用related_name参数(”多对多表名小写”)
b_list_obj=models.B.objects.filter(m2m__a_obj=A_obj)  #m2m对象方式
b_list_obj=models.B.objects.filter(m2m__a_obj_id=A_obj.id) #m2m字段值方式

  方式4(通过多对多字段设置的related_name进行反向调用)

>>> A_obj = models.A.objects.filter(id=1).first()
>>> b_list_obj = models.B.objects.filter(bn__a_obj__name=A_obj.name)
>>> b_list_obj = models.B.objects.filter(bn__a_obj__id=A_obj.id)
>>> for obj in b_list_obj:
...    obj.name
...
'强1'
'强2'
插入:(如果数据表创建时候没有使用related_name参数(”多对多表名小写”)
b_list_obj = models.B.objects.filter(m2m__a_obj__name=A_obj.name) #双下划线+关联表(A表)字段方式
b_list_obj = models.B.objects.filter(m2m__a_obj__id=A_obj.id)

获取B表指定数据对象的所有关联的A表数据

    (方式和上面一样道理的,就是颠倒而已,就不在重复)

M2M表(第三张表)的手动操作增删改查

    

>>> models.M2M.objects.create(b_obj=B_obj,a_obj=A_obj)

>>> models.M2M.objects.create(a_obj_id=3,b_obj_id=3)

    查看数据库

实战Django之Model操作之多对多(ManyToMany)正反调用_第7张图片

    改

>>> models.M2M.objects.filter(id=5).update(b_obj=B_obj,a_obj=A_obj)
1
>>> models.M2M.objects.filter(id=4).update(b_obj_id=3,a_obj_id=3)
1

    查看数据库

实战Django之Model操作之多对多(ManyToMany)正反调用_第8张图片

    删

>>> models.M2M.objects.filter(id=5).delete()
(1, {'modes_handle.M2M': 1})

   查看数据库

实战Django之Model操作之多对多(ManyToMany)正反调用_第9张图片

    sava改

>>> m2m_obj_save = models.M2M.objects.filter(id=4).first()
>>> m2m_obj_save.a_obj = A_obj
>>> m2m_obj_save.b_obj = B_obj
>>> m2m_obj_save.save()

    查看数据库

>>>m2m_obj_save = models.M2M.objects.filter(id=4).first()
>>> m2m_obj_save.a_obj_id = 3
>>> m2m_obj_save.b_obj_id = 3
>>> m2m_obj_save.save()

    查看数据库

实战Django之Model操作之多对多(ManyToMany)正反调用_第10张图片

    3.自动+手动(手动维护第三章表)

        建立表类

跳转:实战之Django之Model建表流程 https://blog.csdn.net/Burgess_zheng/article/details/86564984

路径:project/modes_handle/models.py

from django.db import models
class A(models.Model):
    name = models.CharField(max_length=10)

class B(models.Model):
    name = models.CharField(max_length=10)
    m2m = models.ManyToManyField("A",through="M2M",through_fields=("b_obj","a_obj"))

class M2M(models.Model):
    a_obj = models.ForeignKey("A",related_name="an",on_delete=None)
    b_obj = models.ForeignKey("B",related_name="bn",on_delete=None)


进入项目目录下执行以下面命令(创建表 or 重新生成表结构)
python manage.py makemigrations
python manage.py migrate

        表数据(django自带的sqlite可视化进行添加,当然也可以进行命令添加)

A表

实战Django之Model操作之多对多(ManyToMany)正反调用_第11张图片

B表

实战Django之Model操作之多对多(ManyToMany)正反调用_第12张图片

M2M表

实战Django之Model操作之多对多(ManyToMany)正反调用_第13张图片

        根据类表进行django的shell命令行操作外键正反调用

进入项目目录(执行如下命令进行django提供的shell命令行)

F:\Burgess\Python\pycharm实验脚本\test\project_burgess>python manage.py shell

获取A表某条数据的所有关联的B表数据(和上面手动创建操作一样)
获取B表某条数据的所有关联的A表数据(和上面手动创建操作一样)
M2M表(第三张表)的手动操作(和上面手动创建操作一样)

 

唯一的区别就是B对象可以通过自身的m2m字段进行有限操作(使用B表的m2m字段操作(有限制只允许:查、清))

>>> from modes_handle import models
>>> A_obj = models.A.objects.first()
>>> B_obj = models.B.objects.first()
>>> m2m_obj= models.M2M.objects
>>> B_obj.m2m.all()
, ]>
>>> B_obj.m2m.clear()
>>> B_obj.m2m.all()


 查看数据库

实战Django之Model操作之多对多(ManyToMany)正反调用_第14张图片

目录篇:Django之model操作ORM目录篇 点击跳转
主篇:Django之Model操作之多对多(ManyToMany)正反调用【ORM篇六】点击跳转​​​​​​​

你可能感兴趣的:(Django,Django之model实战篇,Django实战篇【总】)