不做大哥好多年 不做大哥好多年
首页
  • MySQL
  • Redis
  • Elasticsearch
  • Kafka
  • Etcd
  • MongoDB
  • TiDB
  • RabbitMQ
  • 01.GO基础
  • 02.面向对象
  • 03.并发编程
  • 04.常用库
  • 05.数据库操作
  • 06.Beego框架
  • 07.Beego商城
  • 08.GIN框架
  • 09.GIN论坛
  • 10.微服务
  • 01.Python基础
  • 02.Python模块
  • 03.Django
  • 04.Flask
  • 05.SYL
  • 06.Celery
  • 10.微服务
  • 01.Java基础
  • 02.面向对象
  • 03.Java进阶
  • 04.Web基础
  • 05.Spring框架
  • 100.微服务
  • Docker
  • K8S
  • 容器原理
  • Istio
  • 数据结构
  • 算法基础
  • 算法题分类
  • 前置知识
  • PyTorch
  • 01.Python
  • 02.GO
  • 03.Java
  • 04.业务问题
  • 05.关键技术
  • 06.项目常识
  • 10.计算机基础
  • Linux基础
  • Linux高级
  • Nginx
  • KeepAlive
  • ansible
  • zabbix
  • Shell
  • Linux内核

逍遥子

不做大哥好多年
首页
  • MySQL
  • Redis
  • Elasticsearch
  • Kafka
  • Etcd
  • MongoDB
  • TiDB
  • RabbitMQ
  • 01.GO基础
  • 02.面向对象
  • 03.并发编程
  • 04.常用库
  • 05.数据库操作
  • 06.Beego框架
  • 07.Beego商城
  • 08.GIN框架
  • 09.GIN论坛
  • 10.微服务
  • 01.Python基础
  • 02.Python模块
  • 03.Django
  • 04.Flask
  • 05.SYL
  • 06.Celery
  • 10.微服务
  • 01.Java基础
  • 02.面向对象
  • 03.Java进阶
  • 04.Web基础
  • 05.Spring框架
  • 100.微服务
  • Docker
  • K8S
  • 容器原理
  • Istio
  • 数据结构
  • 算法基础
  • 算法题分类
  • 前置知识
  • PyTorch
  • 01.Python
  • 02.GO
  • 03.Java
  • 04.业务问题
  • 05.关键技术
  • 06.项目常识
  • 10.计算机基础
  • Linux基础
  • Linux高级
  • Nginx
  • KeepAlive
  • ansible
  • zabbix
  • Shell
  • Linux内核
  • python基础

  • python模块

  • django

    • 01_Django基础

    • 02_Model数据库操作

      • 01.配置数据库
      • 02.定义模型
      • 03.一对多
      • 04.多对多
        • 01.不创建第三张表推荐(法1)
          • 1.1 创建表
          • 1.2 根据queryset对象操作
        • 02.自己创建第三张关系表(法2)
        • 03.根据外检ID操作(法3)
          • 3.1 创建表
          • 3.2 根据id增删改查
        • 04.ManyToManyField参数
        • 05.values和values_list
      • 05.一大波Model操作
      • 06.F()和Q()查询
      • 07.aggregate和annotate
      • 08.django-admin
    • 03_DRF框架

    • 04_部署

  • flask

  • SYL

  • Celery

  • 微服务

  • python
  • django
  • 02_Model数据库操作
xiaonaiqiang
2021-02-16
目录

04.多对多

# 01.不创建第三张表推荐(法1)

  • 第一种: 自己不创建第三张关系表,有m2m字段: 根据queryset对象增删改查(推荐)

# 1.1 创建表

from django.db import models

class UserInfo(models.Model):
    username = models.CharField(max_length=32)
    def __str__(self):
        return self.username

class UserGroup(models.Model):
    group_name = models.CharField(max_length=64)
    user_info = models.ManyToManyField(to='UserInfo',related_query_name='m2m')

    def __str__(self):
        return self.group_name
1
2
3
4
5
6
7
8
9
10
11
12
13

# 1.2 根据queryset对象操作

from django.shortcuts import HttpResponse
from app01 import models

def orm(request):
    user_info_obj = models.UserInfo.objects.get(username='zhangsan')
    user_info_objs = models.UserInfo.objects.all()

    group_obj = models.UserGroup.objects.get(group_name='group_python')
    group_objs = models.UserGroup.objects.all()

    # 添加: 正向
    group_obj.user_info.add(user_info_obj)
    group_obj.user_info.add(*user_info_objs)
    # 删除:正向
    group_obj.user_info.remove(user_info_obj)
    group_obj.user_info.remove(*user_info_objs)

    # 添加: 反向
    user_info_obj.usergroup_set.add(group_obj)
    user_info_obj.usergroup_set.add(*group_objs)
    # 删除:反向
    user_info_obj.usergroup_set.remove(group_obj)
    user_info_obj.usergroup_set.remove(*group_objs)

    # 查找:正向
    print(group_obj.user_info.all())                                # 查找group_python组中所有用户
    print(group_obj.user_info.all().filter(username='zhangsan'))
    # 查找:反向
    print(user_info_obj.usergroup_set.all())                        # 查找用户zhangsan属于那些组
    print(user_info_obj.usergroup_set.all().filter(group_name='group_python'))


    # 双下划线 正向、反向查找
    # 正向:从用户组表中查找zhangsan属于哪个用户组:[<UserGroup: group_python>]
    print( models.UserGroup.objects.filter(user_info__username='zhangsan'))

    # 反向:从用户表中查询group_python组中有哪些用户:related_query_name='m2m'
    print( models.UserInfo.objects.filter(m2m__group_name='group_python'))


    # 自动创建UserInfo表和UserGroup表中的数据
    '''
    user_list = [{'username':'zhangsan'},
                {'username':'lisi'},
                {'username':'wangwu'},]
    group_list = [{'group_name':'group_python'},
               {'group_name':'group_linux'},
               {'group_name':'group_mysql'},]

    for c in user_list:
        models.UserInfo.objects.create(**c)

    for l in group_list:
        models.UserGroup.objects.create(**l)
    '''

    return HttpResponse('orm')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57

# 02.自己创建第三张关系表(法2)

  • 第二种: 自己创建第三张关系表,无 m2m 字段,自己链表查询
from django.db import models

#表1:主机表
class Host(models.Model):
    nid = models.AutoField(primary_key=True)
    hostname = models.CharField(max_length=32,db_index=True)

#表2:应用表
class Application(models.Model):
    name = models.CharField(max_length=32)

#表3:自定义第三张关联表
class HostToApp(models.Model):
    hobj = models.ForeignKey(to="Host",to_field="nid")
    aobj = models.ForeignKey(to='Application',to_field='id')

# 向第三张表插入数据,建立多对多外键关联
HostToApp.objects.create(hobj_id=1,aobj_id=2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 03.根据外检ID操作(法3)

  • 第三种: 自己不创建第三张关系表,有m2m字段: 根据数字id增删改查

# 3.1 创建表

from django.db import models

class Host(models.Model):
    hostname = models.CharField(max_length=32,db_index=True)

class Group(models.Model):
    group_name = models.CharField(max_length=32)
    m2m = models.ManyToManyField("Host")
1
2
3
4
5
6
7
8

# 3.2 根据id增删改查

from django.shortcuts import HttpResponse
from app01 import models

def orm(request):
    # 使用间接方法对第三张表操作
    obj = models.Group.objects.get(id=1)

    # 1、添加
    obj.m2m.add(1)           # 在第三张表中增加一个条目(1,1)
    obj.m2m.add(2, 3)        # 在第三张表中增加条目(1,2)(1,3)两条关系
    obj.m2m.add(*[1,3])        # 在第三张表中增加条目(1,2)(1,3)两条关系

    # 2、删除
    obj.m2m.remove(1)             # 删除第三张表中的(1,1)条目
    obj.m2m.remove(2, 3)          # 删除第三张表中的(1,2)(1,3)条目
    obj.m2m.remove(*[1, 2, 3])    # 删除第三张表中的(1,1)(1,2)(1,3)条目

    # 3、清空
    obj.m2m.clear()                 # 删除第三张表中application条目等于1的所有条目

    # 4 更新
    obj.m2m.set([1, 2,])             # 第三张表中会删除所有条目,然后创建(1,1)(1,2)条目

    # 5 查找
    print( obj.m2m.all() )           # 等价于 models.UserInfo.objects.all()

    # 6 反向查找: 双下划线
    hosts = models.Group.objects.filter(m2m__id=1)         # 在Host表中id=1的主机同时属于那些组


    # 自动创建Host表和Group表中的数据
    '''
    hostname = [{'hostname':'zhangsan'},
                {'hostname':'lisi'},
                {'hostname':'wangwu'},]
    group_name = [{'group_name':'DBA'},{'group_name':'public'},]

    for h in hostname:
        models.Host.objects.create(**h)
    for u in group_name:
        models.Group.objects.create(**u)
    '''

    return HttpResponse('orm')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

# 04.ManyToManyField参数

  • 创建m2m多对多时ManyToManyField可以添加的参数
1、to,                        # 要进行关联的表名
2、related_name=None,         # 反向操作时,使用的字段名,用于代替 【表名_set】如: obj.表名_set.all()
3、related_query_name=None,   # 反向操作时,使用的连接前缀,用于替换【表名】     
                              # 如: models.UserGroup.objects.filter(表名__字段名=1).values('表名__字段名')
4、limit_choices_to=None,     # 在Admin或ModelForm中显示关联数据时,提供的条件:
                              # - limit_choices_to={'nid__gt': 5}
5、symmetrical=None,          # 用于多对多自关联,symmetrical用于指定内部是否创建反向操作字段
6、through=None,              # 自定义第三张表时,使用字段用于指定关系表
7、through_fields=None,       # 自定义第三张表时,使用字段用于指定关系表中那些字段做多对多关系表
8、db_constraint=True,        # 是否在数据库中创建外键约束
   db_table=None,             # 默认创建第三张表时,数据库中表的名称
1
2
3
4
5
6
7
8
9
10
11

# 05.values和values_list

from django.shortcuts import HttpResponse
from app01 import models

def orm(request):
    # 第一种:values-----获取的内部是字典,拿固定列数
    # 1.1 正向查找: 使用ManyToManyField字段名user_info结合双下划线查询
    models.UserGroup.objects.filter(group_name='group_python').values('group_name', 'user_info__username')

    # 1.2 反向查找: 使用ManyToManyField的related_query_name='m2m',的字段
    models.UserInfo.objects.filter(username='zhangsan').values('username', 'm2m__group_name')


    # 第二种:values_list-----获取的是元组  拿固定列数
    # 2.1 正向查找: 使用ManyToManyField字段名user_info结合双下划线查询
    models.UserGroup.objects.filter(group_name='group_python').values_list('group_name', 'user_info__username')

    # 2.2 反向查找: 使用ManyToManyField的related_query_name='m2m',的字段
    lesson = models.UserInfo.objects.filter(username='zhangsan').values_list('username', 'm2m__group_name')

    # 自动创建UserInfo表和UserGroup表中的数据
    '''
    # user_info_obj = models.UserInfo.objects.get(username='lisi')
    # user_info_objs = models.UserInfo.objects.all()
    #
    # group_obj = models.UserGroup.objects.get(group_name='group_python')
    # group_objs = models.UserGroup.objects.all()
    #
    # group_obj.user_info.add(*user_info_objs)
    # user_info_obj.usergroup_set.add(*group_objs)

    user_list = [{'username':'zhangsan'},
                {'username':'lisi'},
                {'username':'wangwu'},]
    group_list = [{'group_name':'group_python'},
               {'group_name':'group_linux'},
               {'group_name':'group_mysql'},]

    for c in user_list:
        models.UserInfo.objects.create(**c)

    for l in group_list:
        models.UserGroup.objects.create(**l)
    '''

    return HttpResponse('orm')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
上次更新: 2024/3/13 15:35:10
03.一对多
05.一大波Model操作

← 03.一对多 05.一大波Model操作→

最近更新
01
04.数组双指针排序_子数组
03-25
02
08.动态规划
03-25
03
06.回溯算法
03-25
更多文章>
Theme by Vdoing | Copyright © 2019-2025 逍遥子 技术博客 京ICP备2021005373号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式