Django 跨表查询--神奇的双下划线和点-阿里云开发者社区

开发者社区> 余二五> 正文

Django 跨表查询--神奇的双下划线和点

简介:
+关注继续查看

我在django的moles中创建了两个calss,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Project(models.Model):
    name = models.CharField(u'项目名称',max_length=32,blank=True)
    id = models.CharField(u'项目ID',max_length=32,unique=True,primary_key=True,blank=True)
    create_date = models.DateTimeField(u'创建时间', auto_now_add=True)
    update_date = models.DateTimeField(u'更新时间', auto_now=True)
 
    def __unicode__(self):
        return self.name
 
 
class Uhost(models.Model):
    name = models.CharField(u'计算机名',max_length=32,blank=False)
    id = models.CharField(u'实例ID',max_length=32,blank=False,primary_key=True)
    ip = models.GenericIPAddressField(u'IP地址',blank=True,null=True)
    project = models.ForeignKey(Project,verbose_name=u'所属项目',db_constraint=False,on_delete=models.DO_NOTHING,blank=True)
    create_date = models.DateTimeField(u'创建时间', auto_now_add=True)
    update_date = models.DateTimeField(u'更新时间', auto_now=True)
     
    def __unicode__(self):
        return self.name


首先我们要理解两个概念==> Object对象和QuerySet查询集


Object对象

一个object对象就是表中的一条数据,表中所有的字段它都有。例如我取Uhost表中的第一个对象

1
2
3
>>> host = Uhost.objects.all()[0]
>>> print type(host)
<class 'ucloud.models.Uhost'>

对象获取某个值使用“.”

例如:

1
2
3
4
5
6
>>> host.id
u'uhost-3th2rp'
>>> host.ip
u'10.6.13.253'
>>> host.project
<Project: CPMS10>

注意:Uhost表中project字段是一个ForeighKey,当获取host.project时,获取到的结果是一个对象

我们还可以获取这个对象其他值,比如Project表中定义了name、id、create_time、update_time四个字段,我们可以通过下面的方式获取

1
2
3
4
5
6
7
8
>>> host.project.name
u'CPMS10'
>>> host.project.id
u'org-81'
>>> host.project.create_date
datetime.datetime(2017, 3, 6, 12, 21, 7, 296546)
>>> host.project.update_date
datetime.datetime(2017, 5, 19, 16, 19, 8, 925978)

总结:对象获取某一列值(或者说是获取某个属性)的时候,使用点来获取。我们跨表查询时,也是使用点来获取。


上面的例子中,我们获取host的project值还可以使用下面这种方式获取:

1
2
3
4
5
6
>>> host.project_id
u'org-81'
>>> host.project_name
Traceback (most recent call last):
  File "<console>", line 1, in <module>
AttributeError: 'Uhost' object has no attribute 'project_name'

这里我们之所以能获取到project_id这个字段的值是因为,在Uhost表中project字段是ForeignKey,而在数据库中被设置了外键的列,在数据库中的字段名就是本表中的列名 +“_“”+被设置外键的表的那个字段名,而Project表中id是primary_key,所以id列被设置了外键 。

由上可知,host.project.id是跨表查询,而host.project_id并不是跨表查询。因为这个字段在自己表中。



QuerySet查询集:

查询集是一组数据的集合,跟python的list基本一样的。例如获取以下方法可以获取Uhost表中所有对象的ip和name。

1
2
3
4
>>> host2 = Uhost.objects.all().values('ip','name')
>>> print type(host2)
<class 'django.db.models.query.ValuesQuerySet'>
[{'ip': u'10.6.13.253''name': u'dbbackupsyncer2'}, {'ip': u'10.6.30.43''name': u'SRV-CPMS10-WEB16'}, {'ip': u'10.6.20.189''name': u'SRV-CPMS10-WEB15'}, {'ip': u'10.6.14.232''name': u'publicconsole'}, {'ip': u'10.6.10.236''name': u'SRV-CPMS10-WEB14'}, {'ip': u'10.6.10.159''name': u'dbbackupsyncer'}, {'ip': u'10.6.11.73''name': u'\u5b98\u7f51'}, {'ip': u'10.6.7.170''name': u'99exchangedb'}, {'ip': u'10.6.5.22''name': u'dc1'}, {'ip': u'10.6.3.243''name': u'dc2'}, {'ip': u'10.6.2.213''name': u'publicweb'}, {'ip': u'10.6.8.163''name': u'SRV-CPMS10-WEB13'}, {'ip': u'10.10.16.165''name': u'SRV-OTA10-WS04'}, {'ip': u'10.10.31.79''name': u'SRV-OTA10-WS05'}, {'ip': u'10.10.187.86''name': u'SRV-OTA10-WS03'}, {'ip': u'10.10.102.32''name': u'SRV-OTA10-WEB04'}, {'ip': u'10.10.107.144''name': u'SRV-OTA10-WEB03'}, {'ip': u'10.10.112.46''name': u'99datasyncer'}, {'ip': u'10.10.48.121''name': u'SRV-CPMS10-WEB31'}, {'ip': u'10.10.218.108''name': u'SRV-CPMS10-WEB30'}, '...(remaining elements truncated)...']


QuerySet如果跨表查询呢?

我们知道对象跨表查询可以用点,QuerySet可以使用双下划线“__”,例如获取Uhost表中所有对象的project id 和project name,可以这样做:

1
2
3
>>> host2 = Uhost.objects.all().values('ip','name','project__id','project__name')
>>> host2[0]
{'ip': u'10.6.13.253''project__name': u'CPMS10''name': u'dbbackupsyncer2''project__id': u'org-81'}

总结:查询集做跨表查询时,使用双下划线"__"










本文转自 曾哥最爱 51CTO博客,原文链接:http://blog.51cto.com/zengestudy/1933826,如需转载请自行联系原作者

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
OceanBase数据库漫谈
从开发视角、运维视角、数据拆分漫谈OceanBase
23 0
node+mysql+express接口开发数据库连接池
node+mysql+express接口开发数据库连接池
19 0
上云第一课第一期部署MySQL数据库
主要讲述数据的部署以及使用
20 0
node+express controller
Node + Express Controller
15 0
教育培训机构使用阿里云无影桌面优缺点
配置灵活,GPU满足设计产品线,价格低廉,随开随用。
28 0
工商银行实时大数据平台建设历程及展望
中国工商银行大数据平台负责人袁一在 FFA 2021 的分享
32 0
【mockito】单元测试之mockito简单使用
项目使用的是springmvc+mybatis 开发; mock包为 mockito-all;虽然也引用了powermock,但截至目前,还未使用到;如果使用到后续再补相关笔记。
17 0
Node + Express + MySQL 接口开发完整案例
Node + Express + MySQL 接口开发完整案例
24 0
浅谈我对DDD领域驱动设计的理解
DDD的全称为Domain-driven Design,即领域驱动设计。下面我从领域、问题域、领域模型、设计、驱动这几个词语的含义和联系的角度去阐述DDD是如何融入到我们平时的软件开发初期阶段的。要理解什么是领域驱动设计,首先要理解什么是领域,什么是设计,还有驱动是什么意思,什么驱动什么。
13 0
ACP实战特训营RDS(DAY3)
要点记录 1. PolarDB的基本概念 1.1、对比单机数据库优势有哪些:简单易用、极致性能、降低成本、海量存储、安全可靠、快速弹性 1.2 、单机数据库容量瓶颈-单机数据库扩展困难-数据库使用成本过高-分布式数据库应用开发繁琐 2. PolarDB产品系列:集群版-单节点-历史库-多主架构 2.1、集群:一个集群包含一个主节点和多个读节点,最多16个节点,即一个主节点和15个只读节点 2.2、地域:是指物理的数据中心,一般情况下,PolarDB集群应该和ECS实例位于同一地域,以实现最高的访问性能
17 0
+关注
20382
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载