ORM之连表操作

-----------------------------连表的正向操作-------------------------

  在models.py中创建两张表UserType和UserInfo:

from django.db import models

class UserType(models.Model):
"""
用户类型
"""
title = models.CharField(max_length=32) class UserInfo(models.Model):
"""
用户表
"""
name = models.CharField(max_length=32)
age = models.IntegerField()
ut = models.ForeignKey("UserType")

  在views.py中创建数据:

from django.shortcuts import render,HttpResponse,redirect
from app01 import models def data(request):
"""
UserType表 创建数据
UserInfo表 创建数据
:param request:
:return:
"""
models.UserType.objects.create(title='普通用户')
models.UserType.objects.create(title='二逼用户')
models.UserType.objects.create(title='牛逼用户')
models.UserInfo.objects.create(name='wang',age=18,ut_id=1)
models.UserInfo.objects.create(name='george',age=18,ut_id=2)
models.UserInfo.objects.create(name='zhe',age=18,ut_id=3)
models.UserInfo.objects.create(name='hahahha',age=18,ut_id=3)
models.UserInfo.objects.create(name='gggg',age=98,ut_id=2)
models.UserInfo.objects.create(name='llllll',age=38,ut_id=1) return HttpResponse("....")

  在views.py中,获取数据

from django.shortcuts import render,HttpResponse,redirect
from app01 import models def data(request):
"""
UserType表 创建数据
UserInfo表 创建数据
:param request:
:return:
"""
#创建数据
models.UserType.objects.create(title='普通用户')
models.UserType.objects.create(title='二逼用户')
models.UserType.objects.create(title='牛逼用户')
models.UserInfo.objects.create(name='wang',age=18,ut_id=1)
models.UserInfo.objects.create(name='george',age=18,ut_id=2)
models.UserInfo.objects.create(name='zhe',age=18,ut_id=3)
models.UserInfo.objects.create(name='hahahha',age=18,ut_id=3)
models.UserInfo.objects.create(name='gggg',age=98,ut_id=2)
models.UserInfo.objects.create(name='llllll',age=38,ut_id=1) #获取
#获取UserInfo表的全部数据,是QuerySet类型,列表的存储方式[obj,obj,obj]
result = models.UserInfo.objects.all()
#循环result,每一个obj是一行的数据
for obj in result:
#在obj里连表UserType
print(obj.name,obj.age,obj.ut_id,obj.ut.title) return HttpResponse("....")

  UserInfo和UserType两个表关联,UserInfo的外键连UserType的主键。拿到UserInfo的所有信息,就可以拿与UserInfo相关联的UserType的数据。

result = model.UserInfo.object.all()

  与UserInfo有关联的UserType表:

for obj in result:
print(obj.name,obj,age,obj.ut_id,obj.ut_title) #ut_id是UserType表的id,ut_title是UserType中的title
#如果UserType表中,也有Foreigkey字段,也可以继续跨表,接着点就行。

 eg

  在model中:

from django.db import models

class Foo(models.Model):
caption = models.CharField(max_length=32) class UserInfo(models.Model):
#主键会自行创建,也可自己创建,nid为字段
nid = models.BigAutoField(primary_key=True)
username = models.CharField(max_length=32)
password = models.CharField(max_length=64)
#增加列,在增加是,可以定义为空,也可定义为默认值
age = models.IntegerField(null=True)
# age = models.IntegerField(default=1) #外键关联UserGroup表,代表UserGroup的一行数据
usergroup = models.ForeignKey("UserGroup",null=True) class UserGroup(models.Model):
#隐藏id,Django的ORM会加的
title = models.CharField(max_length=32)
fo = models.ForeignKey('Foo',null=True)

model

  在views中:  

from models同级目录文件 import models

def test(request):
result = models.UserInfo.objects.all()
print(result)
for i in result:
print(i.username,i.usergroup.title,i.usergroup.fo.caption)

views

在print(i.username,i.usergroup.title,i.usergroup.fo.caption)中,有跨一张表的,和两张表的。

i.username:拿的本表的

i.usergroup.title 跨一张表的

i.usergroup.fo.caption 跨两张表的

在UserInfo中,usergroup是FK字段

obj = models.UserInfo.object.all().first()

print(obj.username,obj.password,obj.age,obj.usergroup.title)

在这里,first是只拿取第一条数据。

------- 反向关联表:一个用户类型下可以有很多用户 -------------

from django.shortcuts import render,HttpResponse,redirect
from app01 import models def data(request):
#创建数据
models.UserType.objects.create(title='普通用户')
models.UserType.objects.create(title='二逼用户')
models.UserType.objects.create(title='牛逼用户')
models.UserInfo.objects.create(name='wang',age=18,ut_id=1)
models.UserInfo.objects.create(name='george',age=18,ut_id=2)
models.UserInfo.objects.create(name='llllll',age=38,ut_id=1) #获取
#获取UserInfo表的全部数据,是QuerySet类型,列表的存储方式[obj,obj,obj]
result = models.UserInfo.objects.all()
#循环result,每一个obj是一行的数据
for obj in result:
#在obj里连表UserType
print(obj.name,obj.age,obj.ut_id,obj.ut.title) #反向操作:UserType,表名小写_set.all() 就是反向查找
obj = models.UserType.objects.all().first()
print('用户类型',obj.id,obj.title,obj.userinfo_set.all())
for row in obj.userinfo_set.all(): #obj是UserType表的别名,obj.userinfo_set可以查到UserInfo里的数据。通过UserType找UserInfo。
print(row.name,row.age)
return HttpResponse("....")

  只要表有外键,就会有一个不显示字段的_set数据,拿UserType说,_set反向查到的是所用属于某一个ID字段的数据。  

result = model.UserType.object.all()
for item in result:
print(item.title,item.userinfo_set.filter(name='george')) #这里还可以.filter
#这里item.userinfo_set.all 是拿到每个用户类型的所用相关数据。
#但是.filter是在每个用户类型里的用户数据,进行二次筛选。

  在去ORM中拿数据时,单个数据是obj类型。多个数据是QuerySet 列表类型。

  但是,在生产中,会有如下的个别情况:

  其一:

result = models.UserInfo.object.all().values("id","name") #values里写UserInfo的字段名,作为值。这样就只取id列和name列

  但问题点在于,这个类型是什么。他是一个字典的QuerySet类型:

#QuerySet[{'id':'XXX','name':'george'}]
#这是for循环result:
for row in result:
print(row) #其print的结果是字典的形式。

  其二:

result = models.UserInfo.object.all().values_list("id","name") #这里拿到的values_list是元祖类型

  这个values_list 是元组类型。

#QuerySet[(1,'george')]
for row in result:
print(row) #其结果是元组的形式呈现。

  所以,数据获取多个数据时,分三个情况:

  1、QuerySet类型是基本的Set类型:查询数据时的方式。

#[obj,obj,obj,]
models.UserInfo.objects.all()
models.UserInfo.objects.filter(id__gt=1)

  每一个基本的QuerySet类型是可以for循环点出表里的是字段: 

result = models.UserInfo.object.all()
for item in result:
print(item.id,item.name,item.ut.title)  

  2、QuerySet类型是列表的,正反向查询:

#[{id:1,name:fd},{id:2,name:ffdd},{id:3,name:fffddd},]
models.UserInfo.objects.all().values("id","name")
models.UserInfo.objects.filter(id__gt=1).values("id":"name")

  每个QuerySet类型是字典,在跨表查询时,就会遇到问题,解决方法是在查询时就做好跨表操作。

  关键操作是在ut跨表时用双下划线“__”。  

result = models.UserInfo.object.all().values("id","name","ut__title")
for item in result:
print(item["id"],item["name"],item["ut__title"]) 

  3、QuerySet类型是字典和元组,连表要加双下划线“__”。

#[(1,"df"),(2,"ddff"),(3,"dddfff"),]
models.UserInfo.objects.all().values_list(id"","name")
models.UserInfo.objects.filter(id__gt=1).values_list("id":"name")

  QuerySet类型是元组,操作方式和字典类似。

result = models.UserInfo.object.all().values_list("id","name","ut__title")
for item in result:
print(item[0],item[1],item[2]) 

  在反向连表中,关于连表取值的个数问题:

  values和values_list 的操作一样。反向操作都是直接小写表名

    v = models.UserType.objects.values("id","title")
#这样是UserType表有几行数据就拿几行数据 v = models.UserType.objects.values("id","title","userinfo")
#这样是以UserInfo和UserType的数据去获取,所以行数是不一样的,因为UserInfo和UserType有关联关系。所以有关联关系的数据有多少行,就拿多少行。然后在单独获取UserInfo没有关联的UserType的字段。 v = models.UserType.objects.values("id","title","userinfo__name")
#双下划线也可以用在这里进行使用。

  所以在前面的表,比如UserType,都会显示拿到的所以数据。

-------- END --------

ORM之连表操作的更多相关文章

  1. Django中模型层中ORM的单表操作

    ORM概念: MVC或者MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库,这极大的减轻了开发人员 ...

  2. ORM的单表操作

    ORM的单表操作 MTV框架包含一个重要的部分就是ORM----对象关系映射(Object Relational Mapping),它实现了数据模型与数据库的解耦,即数据模型的设计.利用它我们不需要依 ...

  3. Django学习手册 - ORM 数据创建/表操作 汇总

    ORM 查询的数据类型: QuerySet与惰性机制(可以看作是一个列表) 所谓惰性机制:表名.objects.all()或者.filter()等都只是返回了一个QuerySet(查询结果集对象),它 ...

  4. ORM 简介 单表操作

    cls超 Django基础五之django模型层(一)单表操作 本节目录 一 ORM简介 二 单表操作 三xxx 一 ORM简介 MVC或者MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型 ...

  5. Django中模型层中ORM的多表操作

    ORM的多表创建(一对一.一对多,多对多): 1模型创建 实例:我们来假定下面这些概念,字段和关系 作者模型:一个作者有姓名和年龄. 作者详细模型:把作者的详情放到详情表,包含生日,手机号,家庭住址等 ...

  6. Django开发:(3.1)ORM:单表操作

    MVC或者MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库,这极大的减轻了开发人员的工作量,不需 ...

  7. ORM之单表操作

    ORM简介 MVC或者MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库,这极大的减轻了开发人员的 ...

  8. Django开发:(3.2)ORM:多表操作

    表关系总结: 一对多:在多的表中建立关联字段 多对多:创建第三张表(关联表):id 和 两个关联字段 一对一:在两张表中的任意一张表中建立关联字段(关联字段一定要加 unique 约束) 子查询:一次 ...

  9. ORM之多表操作

    一.创建模型 from django.db import models # Create your models here. class Book(models.Model): nid = model ...

随机推荐

  1. 关于element-ui的diallog拖动的实现

    先给下载地址 https://files.cnblogs.com/files/maruihua/el-dragDialog.rar 需要注意的是如果给模态框加入拖动指令,一些定位样式会出问题,需谨慎 ...

  2. 【原创】《从0开始学Elasticsearch》—初识Elasticsearch

    目录 1. Elasticsearch 是什么2. Elasticsearch 中基本概念3. Elasticsearch 安装4. 访问 Elasticsearch 1. Elasticsearch ...

  3. 使用Quartz实现定时作业

    该文章是系列文章 基于.NetCore和ABP框架如何让Windows服务执行Quartz定时作业 的其中一篇. Quartz是一个开源的作业调度框架,准确的称谓应该是 Quartz.Net,它是Ja ...

  4. 【SpringCloud构建微服务系列】微服务网关Zuul

    一.为什么要用微服务网关 在微服务架构中,一般不同的微服务有不同的网络地址,而外部客户端(如手机APP)可能需要调用多个接口才能完成一次业务需求.例如一个电影购票的手机APP,可能会调用多个微服务的接 ...

  5. windows 下使用命令行操作ftp

    open 192.168.10.6     (连接到FTP主机) User allan\ftp            (用户连接验证,注意这里的用户用到的是FTP服务器端创建的用户名) 123     ...

  6. [POI2004]GRA

    Description 让我们考虑一个在m x 1 的板子上玩的游戏,板子被从1 到 m编号. 现在板子上有n 个棋子, 每个都严格占据板子上的一个格子. 没有一个棋子占据格子m. 每个单独的移动遵循 ...

  7. DP(DAG) UVA 437 The Tower of Babylon

    题目传送门 题意:给出一些砖头的长宽高,砖头能叠在另一块上要求它的长宽都小于下面的转头的长宽,问叠起来最高能有多高 分析:设一个砖头的长宽高为x, y, z,那么想当于多了x, z, y 和y, x, ...

  8. 如何隐藏electron窗体的菜单栏

    electron中默认带有顶部菜单栏,有时候我们的应用不需要. 再main.js文件中设置 const electron = require('electron') const path = requ ...

  9. Spring注解驱动开发之AOP

    前言:现今SpringBoot.SpringCloud技术非常火热,作为Spring之上的框架,他们大量使用到了Spring的一些底层注解.原理,比如@Conditional.@Import.@Ena ...

  10. JS中的对象之原型

    对象 ECMAScript做为一个高度抽象的面向对象语言,是通过_对象_来交互的.即使ECMAScript里边也有_基本类型_,但是,当需要的时候,它们也会被转换成对象. 一个对象就是一个属性集合,并 ...