Django 跨表查询--神奇的双下划线和点
我在django的moles中创建了两个calss,如下:
classProject(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):returnself.nameclassUhost(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):returnself.name
首先我们要理解两个概念==> Object对象和QuerySet查询集
Object对象:
一个object对象就是表中的一条数据,表中所有的字段它都有。例如我取Uhost表中的第一个对象
>>>host=Uhost.objects.all()[0]>>>printtype(host)<class'ucloud.models.Uhost'>
对象获取某个值使用“.”
例如:
>>>host.idu'uhost-3th3rp'>>>host.ipu'10.6.13.253'>>>host.project<Project:CPMS10>
注意:Uhost表中project字段是一个ForeighKey,当获取host.project时,获取到的结果是一个对象
我们还可以获取这个对象其他值,比如Project表中定义了name、id、create_time、update_time四个字段,我们可以通过下面的方式获取
>>>host.project.nameu'CPMS10'>>>host.project.idu'org-81'>>>host.project.create_datedatetime.datetime(2017,3,6,12,21,7,296546)>>>host.project.update_datedatetime.datetime(2017,5,19,16,19,8,925978)
总结:对象获取某一列值(或者说是获取某个属性)的时候,使用点来获取。我们跨表查询时,也是使用点来获取。
上面的例子中,我们获取host的project值还可以使用下面这种方式获取:
>>>host.project_idu'org-81'>>>host.project_nameTraceback(mostrecentcalllast):File"<console>",line1,in<module>AttributeError:'Uhost'objecthasnoattribute'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')>>>printtype(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'},'...(remainingelementstruncated)...']
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'}
总结:查询集做跨表查询时,使用双下划线"__"
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。