Django跨表查询--神奇的双下划线和点-创新互联
我在django的moles中创建了两个calss,如下:
创新互联公司主营辉县网站建设的网络公司,主营网站建设方案,app软件定制开发,辉县h5小程序开发搭建,辉县网站营销推广欢迎辉县等地区企业咨询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表中的第一个对象
>>> host = Uhost.objects.all()[0] >>> print type(host)
对象获取某个值使用“.”
例如:
>>> host.id u'uhost-3th3rp' >>> host.ip u'10.6.13.253' >>> host.project
注意:Uhost表中project字段是一个ForeighKey,当获取host.project时,获取到的结果是一个对象
我们还可以获取这个对象其他值,比如Project表中定义了name、id、create_time、update_time四个字段,我们可以通过下面的方式获取
>>> 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值还可以使用下面这种方式获取:
>>> host.project_id u'org-81' >>> host.project_name Traceback (most recent call last): File "", line 1, in 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。
>>> host2 = Uhost.objects.all().values('ip','name') >>> print type(host2)[{'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,可以这样做:
>>> 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'}
总结:查询集做跨表查询时,使用双下划线"__"
另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。
名称栏目:Django跨表查询--神奇的双下划线和点-创新互联
分享链接:http://azwzsj.com/article/phppi.html