• 技术文章 >Python框架 >Django

    Django之ORM连表操作

    爱喝马黛茶的安东尼爱喝马黛茶的安东尼2019-07-02 10:48:52原创2165

    ORM连表操作

    我们在学习django中的orm的时候,我们可以把一对多,多对多,分为正向和反向查找两种方式。

    正向查找:ForeignKey在 UserInfo表中,如果从UserInfo表开始向其他的表进行查询,这个就是正向操作,反之如果从UserType表去查询其他的表这个就是反向操作。

    (1)一对多:models.ForeignKey(其他表)

    (2)多对多:models.ManyToManyField(其他表)

    (3)一对一:models.OneToOneField(其他表)

    正向连表操作总结:

    所谓正、反向连表操作的认定无非是Foreign_Key字段在哪张表决定的,

    Foreign_Key字段在哪张表就可以哪张表使用Foreign_Key字段连表,反之没有Foreign_Key字段就使用与其关联的小写表名;

    1对多:对象.外键.关联表字段,values(外键字段__关联表字段)

    多对多:外键字段.all()

    反向连表操作总结:

    通过value、value_list、fifter 方式反向跨表:小写表名__关联表字段

    通过对象的形式反向跨表:小写表面_set().all()

    前端ajax需要携带的参数

    根据前端参数,返回不同数据库结果

    应用场景:

    (1)一对多:当一张表中创建一行数据时,有一个单选的下拉框(可以被重复选择)

    例如:创建用户信息时候,需要选择一个用户类型【普通用户】【金牌用户】【铂金用户】等。

    (2)多对多:在某表中创建一行数据是,有一个可以多选的下拉框。

    例如:创建用户信息,需要为用户指定多个爱好。

    a.png

    (3)一对一:在某表中创建一行数据时,有一个单选的下拉框(下拉框中的内容被用过一次就消失了。

    例如:原有含10列数据的一张表保存相关信息,经过一段时间之后,10列无法满足需求,需要为原来的表再添加5列数据。

    1对多

    如果A表的1条记录对应B表中N条记录成立,两表之间就是1对多关系;在1对多关系中 A表就是主表,B表为子表,ForeignKey字段就建在子表;

    如果B表的1条记录也对应A表中N条记录,两表之间就是双向1对多关系,也称为多对多关系;

    在orm中设置如果 A表设置了外键字段user=models.ForeignKey('UserType')到B表(注意外键表名加引号)

    就意味着 写在写A表的B表主键, (一列),代表B表的多个(一行)称为1对多,

    查询

    总结:利用orm获取 数据库表中多个数据

    获取到的数据类型本质上都是 queryset类型,

    类似于列表,

    内部有3种表现形式(对象,字典,列表)

    modle.表名.objects.all()

    modle.表名.objects.values()

    modle.表名.objects.values()

    跨表

    正操作

    所以表间只要有外键关系就可以一直点下去。

    所以可以通过obj.外键.B表的列表跨表操作(注意!!orm连表操作必须选拿单个对象,不像SQL中直接表和表join就可以了)

    print(obj.cls.title)

    foreignkey字段在那个表里,那个表里一个"空格"代表那个表的多个(一行)

    class UserGroup(models.Model):
                """
                部门 3
                """
                title = models.CharField(max_length=32)
            class UserInfo(models.Model):
                """
                员工4
                """
                nid = models.BigAutoField(primary_key=True)
                user = models.CharField(max_length=32)
                password = models.CharField(max_length=64)
                age = models.IntegerField(default=1)
                # ug_id 1
                ug = models.ForeignKey("UserGroup",null=True)

    1. 在取得时候跨表

    q = UserInfo.objects.all().first()

    q.ug.title

    2. 在查的时候就跨表了

    UserInfo.objects.values('nid','ug_id')

    UserInfo.objects.values('nid','ug_id','ug__title') #注意正向连表是 外键__外键列 反向是小写的表名

    3. UserInfo.objects.values_list('nid','ug_id','ug__title')

    反向连表:

    反向操作无非2种方式:

    (1)通过对象的形式反向跨表:小写表面_set().all()

    (2)通过value和value_list方式反向跨表:小写表名__字段

    1. 小写的表名_set 得到有外键关系的对象

    obj = UserGroup.objects.all().first()

    result = obj.userinfo_set.all() [userinfo对象,userinfo对象,]

    2. 小写的表名 得到有外键关系的列 #因为使用values取值取得是字典的不是对象,所以需要 小写表名(外键表)__

    v = UserGroup.objects.values('id','title')

    v = UserGroup.objects.values('id','title','小写的表名称')

    v = UserGroup.objects.values('id','title','小写的表名称__age')

    3. 小写的表名 得到有外键关系的列

    v = UserGroup.objects.values_list('id','title')

    v = UserGroup.objects.values_list('id','title','小写的表名称')

    v = UserGroup.objects.values_list('id','title','小写的表名称__age')

    1对多自关联( 由原来的2张表,变成一张表! )

    想象有第二张表,关联自己表中的行

    s.png

    d.png

    相关推荐:《Python视频教程

    代码

        class Comment(models.Model):
                    """
                    评论表
                    """
                    news_id = models.IntegerField()            # 新闻ID
                    content = models.CharField(max_length=32)  # 评论内容
                    user = models.CharField(max_length=32)     # 评论者
                    reply = models.ForeignKey('Comment',null=True,blank=True,related_name='xxxx') #回复ID

    多对多:

    1、自己写第3张关系表

    ORM多对多查询:

    女士表:

    a.png

    男生表:

    s.png

    男女关系表

    d.png

    多对跨表操作

    #获取方少伟有染的女孩
        obj=models.Boy.objects.filter(name='方少伟').first()
        obj_list=obj.love_set.all()
        for row in obj_list:
            print(row.g.nike)
        # 获取和苍井空有染的男孩
        obj=models.Girl.objects.filter(nike='苍井空').first()
        user_list=obj.love_set.all()
        for row in  user_list:
            print(row.b.name)

    多对多关系表 数据查找思路

    (1)找到该对象

    (2)通过该对象 反向操作 找到第三张关系表

    (3)通过第三张关系表 正向操作 找到 和该对象有关系对象

    总结

    只要对象1和对象2 中间有关系表建立了关系; 对象1反向操作 到关系表 ,关系表正向操作到对象2,反之亦然。

    2、第3张关系表不用写(m=models.ManyToManyField(' 要关联的表') 自动生成)

    1562035302215495.png

    由于 DjangoORM中一个类名对应一张表,要想操作表就modles.类直接操作那张表,但使用ManyToManyField字段生成 “第三张”关系表怎么操作它呢?

    答案:通过单个objd对象 间接操作

    class Boy(models.Model):
        name = models.CharField(max_length=32)
        m = models.ManyToManyField('Girl',through="Love",through_fields=('b','g',))
    class Girl(models.Model):
        nick = models.CharField(max_length=32)
        m = models.ManyToManyField('Boy')

    正向操作: obj.m.all()

    obj = models.Boy.objects.filter(name='方少伟').first()
        print(obj.id,obj.name)
        obj.m.add(2)
        obj.m.add(2,4)
        obj.m.add(*[1,])
        obj.m.remove(1)
        obj.m.remove(2,3)
        obj.m.remove(*[4,])
        obj.m.set([1,])
        q = obj.m.all()
        # [Girl对象]
        print(q)
        obj = models.Boy.objects.filter(name='方少伟').first()
        girl_list = obj.m.all()
        obj = models.Boy.objects.filter(name='方少伟').first()
        girl_list = obj.m.all()
        girl_list = obj.m.filter(nick='小鱼')
        print(girl_list)
        obj = models.Boy.objects.filter(name='方少伟').first()
        obj.m.clear()

    反向操作 :obj.小写的表名_set

    多对多和外键跨表一样都是 小写的表名_set

    3、既自定义第三张关系表 也使用ManyToManyField('Boy')字段(杂交类型)

    ManyToManyField()字段创建第3张关系表,可以使用字段跨表查询,但无法直接操作第3张表,

    自建第3表关系表可以直接操作,但无法通过字段 查询,我们可以把他们结合起来使用;

    作用:

    (1)既可以使用字段跨表查询,也可以直接操作第3张关系表

    (2)obj.m.all() 只有查询和清空方法

    外键反向查找别名(方便反向查找)

    在写ForeignKey字段的时候,如果想要在反向查找时不使用默认的 小写的表名_set,就在定义这个字段的时间加related参数!

    related_name、related_query_name 字段=什么别名 反向查找时就使用什么别名!

    反向查找:

    设置了related_query_name 反向查找时就是obj.别名_set.all()保留了_set

    related_query_name

    related_name

    反向查找:

    设置了relatedname就是 反向查找时就说 obj.别名.all()

    多对多自关联(由原来的3张表,变成只有2张表)

    把两张表通过 choices字段合并为一张表

    ‘第三张关系表’ 使用models.ManyToManyField('Userinfo')生成

    特性:

    obj = models.UserInfo.objects.filter(id=1).first() 获取对象

    (1)查询第三张关系表前面那一列:obj.m

    select xx from xx where from_userinfo_id = 1

    (2)查询第三张关系表后面那一列:obj.userinfo_set

    select xx from xx where to_userinfo_id = 1

    多对多自关联特性:

    x.png

    ManyToManyField生成的第三张表

    cc.png

    专题推荐:django orm 连表
    上一篇:Django之modles.py创建表 下一篇:Django如何自定义Field实现多语言

    相关文章推荐

    • Django之modles.py创建表

    全部评论我要评论

    © 2021 Python学习网 苏ICP备2021003149号-1

  • 取消发布评论
  • 

    Python学习网