• 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 根据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')


    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)

    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")

    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')

    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,             # 默认创建第三张表时,数据库中表的名称

    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'
  • 相关阅读:
    Android进程生命周期与ADJ
    四大组件之综述
    Linux进程pid分配法
    Linux的进程管理
    Linux硬盘管理
    Linux用户管理
    Linux命令行使用
    vim技巧5 常用操作
    vim技巧4 删除/保留文本中匹配行
    如何绘制UML图?
  • 原文地址:https://www.cnblogs.com/xiaoxiamiaichiyu/p/14789028.html
Copyright © 2020-2023  润新知