溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Django 跨表查詢--神奇的雙下劃線和點(diǎn)

發(fā)布時(shí)間:2020-06-29 04:26:19 來(lái)源:網(wǎng)絡(luò) 閱讀:11515 作者:zenge_blog 欄目:開(kāi)發(fā)技術(shù)

我在django的moles中創(chuàng)建了兩個(gè)calss,如下:

class Project(models.Model):
    name = models.CharField(u'項(xiàng)目名稱',max_length=32,blank=True)
    id = models.CharField(u'項(xiàng)目ID',max_length=32,unique=True,primary_key=True,blank=True)
    create_date = models.DateTimeField(u'創(chuàng)建時(shí)間', auto_now_add=True)
    update_date = models.DateTimeField(u'更新時(shí)間', auto_now=True)

    def __unicode__(self):
        return self.name


class Uhost(models.Model):
    name = models.CharField(u'計(jì)算機(jī)名',max_length=32,blank=False)
    id = models.CharField(u'實(shí)例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'所屬項(xiàng)目',db_constraint=False,on_delete=models.DO_NOTHING,blank=True)
    create_date = models.DateTimeField(u'創(chuàng)建時(shí)間', auto_now_add=True)
    update_date = models.DateTimeField(u'更新時(shí)間', auto_now=True)
    
    def __unicode__(self):
        return self.name


首先我們要理解兩個(gè)概念==> Object對(duì)象和QuerySet查詢集


Object對(duì)象

一個(gè)object對(duì)象就是表中的一條數(shù)據(jù),表中所有的字段它都有。例如我取Uhost表中的第一個(gè)對(duì)象

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

對(duì)象獲取某個(gè)值使用“.”

例如:

>>> host.id
u'uhost-3th3rp'
>>> host.ip
u'10.6.13.253'
>>> host.project
<Project: CPMS10>

注意:Uhost表中project字段是一個(gè)ForeighKey,當(dāng)獲取host.project時(shí),獲取到的結(jié)果是一個(gè)對(duì)象

我們還可以獲取這個(gè)對(duì)象其他值,比如Project表中定義了name、id、create_time、update_time四個(gè)字段,我們可以通過(guò)下面的方式獲取

>>> 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)

總結(jié):對(duì)象獲取某一列值(或者說(shuō)是獲取某個(gè)屬性)的時(shí)候,使用點(diǎn)來(lái)獲取。我們跨表查詢時(shí),也是使用點(diǎn)來(lái)獲取。


上面的例子中,我們獲取host的project值還可以使用下面這種方式獲?。?/p>

>>> 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這個(gè)字段的值是因?yàn)?,在Uhost表中project字段是ForeignKey,而在數(shù)據(jù)庫(kù)中被設(shè)置了外鍵的列,在數(shù)據(jù)庫(kù)中的字段名就是本表中的列名 +“_“”+被設(shè)置外鍵的表的那個(gè)字段名,而Project表中id是primary_key,所以id列被設(shè)置了外鍵 。

由上可知,host.project.id是跨表查詢,而host.project_id并不是跨表查詢。因?yàn)檫@個(gè)字段在自己表中。



QuerySet查詢集:

查詢集是一組數(shù)據(jù)的集合,跟python的list基本一樣的。例如獲取以下方法可以獲取Uhost表中所有對(duì)象的ip和name。

>>> 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如果跨表查詢呢?

我們知道對(duì)象跨表查詢可以用點(diǎn),QuerySet可以使用雙下劃線“__”,例如獲取Uhost表中所有對(duì)象的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'}

總結(jié):查詢集做跨表查詢時(shí),使用雙下劃線"__"


向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI