天天看點

Django 跨表查詢--神奇的雙下劃線和點

我在django的moles中建立了兩個calss,如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

<code>class Project(models.Model):</code>

<code>    </code><code>name = models.CharField(u</code><code>'項目名稱'</code><code>,max_length=32,blank=True)</code>

<code>    </code><code>id</code> <code>= models.CharField(u</code><code>'項目ID'</code><code>,max_length=32,unique=True,primary_key=True,blank=True)</code>

<code>    </code><code>create_date = models.DateTimeField(u</code><code>'建立時間'</code><code>, auto_now_add=True)</code>

<code>    </code><code>update_date = models.DateTimeField(u</code><code>'更新時間'</code><code>, auto_now=True)</code>

<code>    </code><code>def __unicode__(self):</code>

<code>        </code><code>return</code> <code>self.name</code>

<code>class Uhost(models.Model):</code>

<code>    </code><code>name = models.CharField(u</code><code>'計算機名'</code><code>,max_length=32,blank=False)</code>

<code>    </code><code>id</code> <code>= models.CharField(u</code><code>'執行個體ID'</code><code>,max_length=32,blank=False,primary_key=True)</code>

<code>    </code><code>ip = models.GenericIPAddressField(u</code><code>'IP位址'</code><code>,blank=True,null=True)</code>

<code>    </code><code>project = models.ForeignKey(Project,verbose_name=u</code><code>'所屬項目'</code><code>,db_constraint=False,on_delete=models.DO_NOTHING,blank=True)</code>

<code>    </code> 

首先我們要了解兩個概念==&gt; Object對象和QuerySet查詢集

Object對象:

一個object對象就是表中的一條資料,表中所有的字段它都有。例如我取Uhost表中的第一個對象

<code>&gt;&gt;&gt; host </code><code>=</code> <code>Uhost.objects.</code><code>all</code><code>()[</code><code>0</code><code>]</code>

<code>&gt;&gt;&gt; </code><code>print</code> <code>type</code><code>(host)</code>

<code>&lt;</code><code>class</code> <code>'ucloud.models.Uhost'</code><code>&gt;</code>

對象擷取某個值使用“.”

例如:

<code>&gt;&gt;&gt; host.</code><code>id</code>

<code>u</code><code>'uhost-3th2rp'</code>

<code>&gt;&gt;&gt; host.ip</code>

<code>u</code><code>'10.6.13.253'</code>

<code>&gt;&gt;&gt; host.project</code>

<code>&lt;Project: CPMS10&gt;</code>

注意:Uhost表中project字段是一個ForeighKey,當擷取host.project時,擷取到的結果是一個對象

我們還可以擷取這個對象其他值,比如Project表中定義了name、id、create_time、update_time四個字段,我們可以通過下面的方式擷取

<code>&gt;&gt;&gt; host.project.name</code>

<code>u</code><code>'CPMS10'</code>

<code>&gt;&gt;&gt; host.project.</code><code>id</code>

<code>u</code><code>'org-81'</code>

<code>&gt;&gt;&gt; host.project.create_date</code>

<code>datetime.datetime(2017, 3, 6, 12, 21, 7, 296546)</code>

<code>&gt;&gt;&gt; host.project.update_date</code>

<code>datetime.datetime(2017, 5, 19, 16, 19, 8, 925978)</code>

總結:對象擷取某一列值(或者說是擷取某個屬性)的時候,使用點來擷取。我們跨表查詢時,也是使用點來擷取。

上面的例子中,我們擷取host的project值還可以使用下面這種方式擷取:

<code>&gt;&gt;&gt; host.project_id</code>

<code>&gt;&gt;&gt; host.project_name</code>

<code>Traceback (most recent call last):</code>

<code>  </code><code>File </code><code>"&lt;console&gt;"</code><code>, line 1, </code><code>in</code> <code>&lt;module&gt;</code>

<code>AttributeError: </code><code>'Uhost'</code> <code>object has no attribute </code><code>'project_name'</code>

這裡我們之是以能擷取到project_id這個字段的值是因為,在Uhost表中project字段是ForeignKey,而在資料庫中被設定了外鍵的列,在資料庫中的字段名就是本表中的列名 +“_“”+被設定外鍵的表的那個字段名,而Project表中id是primary_key,是以id列被設定了外鍵 。

由上可知,host.project.id是跨表查詢,而host.project_id并不是跨表查詢。因為這個字段在自己表中。

QuerySet查詢集:

查詢集是一組資料的集合,跟python的list基本一樣的。例如擷取以下方法可以擷取Uhost表中所有對象的ip和name。

<code>&gt;&gt;&gt; host2 = Uhost.objects.all().values(</code><code>'ip'</code><code>,</code><code>'name'</code><code>)</code>

<code>&gt;&gt;&gt; print </code><code>type</code><code>(host2)</code>

<code>&lt;class </code><code>'django.db.models.query.ValuesQuerySet'</code><code>&gt;</code>

<code>[{</code><code>'ip'</code><code>: u</code><code>'10.6.13.253'</code><code>, </code><code>'name'</code><code>: u</code><code>'dbbackupsyncer2'</code><code>}, {</code><code>'ip'</code><code>: u</code><code>'10.6.30.43'</code><code>, </code><code>'name'</code><code>: u</code><code>'SRV-CPMS10-WEB16'</code><code>}, {</code><code>'ip'</code><code>: u</code><code>'10.6.20.189'</code><code>, </code><code>'name'</code><code>: u</code><code>'SRV-CPMS10-WEB15'</code><code>}, {</code><code>'ip'</code><code>: u</code><code>'10.6.14.232'</code><code>, </code><code>'name'</code><code>: u</code><code>'publicconsole'</code><code>}, {</code><code>'ip'</code><code>: u</code><code>'10.6.10.236'</code><code>, </code><code>'name'</code><code>: u</code><code>'SRV-CPMS10-WEB14'</code><code>}, {</code><code>'ip'</code><code>: u</code><code>'10.6.10.159'</code><code>, </code><code>'name'</code><code>: u</code><code>'dbbackupsyncer'</code><code>}, {</code><code>'ip'</code><code>: u</code><code>'10.6.11.73'</code><code>, </code><code>'name'</code><code>: u</code><code>'\u5b98\u7f51'</code><code>}, {</code><code>'ip'</code><code>: u</code><code>'10.6.7.170'</code><code>, </code><code>'name'</code><code>: u</code><code>'99exchangedb'</code><code>}, {</code><code>'ip'</code><code>: u</code><code>'10.6.5.22'</code><code>, </code><code>'name'</code><code>: u</code><code>'dc1'</code><code>}, {</code><code>'ip'</code><code>: u</code><code>'10.6.3.243'</code><code>, </code><code>'name'</code><code>: u</code><code>'dc2'</code><code>}, {</code><code>'ip'</code><code>: u</code><code>'10.6.2.213'</code><code>, </code><code>'name'</code><code>: u</code><code>'publicweb'</code><code>}, {</code><code>'ip'</code><code>: u</code><code>'10.6.8.163'</code><code>, </code><code>'name'</code><code>: u</code><code>'SRV-CPMS10-WEB13'</code><code>}, {</code><code>'ip'</code><code>: u</code><code>'10.10.16.165'</code><code>, </code><code>'name'</code><code>: u</code><code>'SRV-OTA10-WS04'</code><code>}, {</code><code>'ip'</code><code>: u</code><code>'10.10.31.79'</code><code>, </code><code>'name'</code><code>: u</code><code>'SRV-OTA10-WS05'</code><code>}, {</code><code>'ip'</code><code>: u</code><code>'10.10.187.86'</code><code>, </code><code>'name'</code><code>: u</code><code>'SRV-OTA10-WS03'</code><code>}, {</code><code>'ip'</code><code>: u</code><code>'10.10.102.32'</code><code>, </code><code>'name'</code><code>: u</code><code>'SRV-OTA10-WEB04'</code><code>}, {</code><code>'ip'</code><code>: u</code><code>'10.10.107.144'</code><code>, </code><code>'name'</code><code>: u</code><code>'SRV-OTA10-WEB03'</code><code>}, {</code><code>'ip'</code><code>: u</code><code>'10.10.112.46'</code><code>, </code><code>'name'</code><code>: u</code><code>'99datasyncer'</code><code>}, {</code><code>'ip'</code><code>: u</code><code>'10.10.48.121'</code><code>, </code><code>'name'</code><code>: u</code><code>'SRV-CPMS10-WEB31'</code><code>}, {</code><code>'ip'</code><code>: u</code><code>'10.10.218.108'</code><code>, </code><code>'name'</code><code>: u</code><code>'SRV-CPMS10-WEB30'</code><code>}, </code><code>'...(remaining elements truncated)...'</code><code>]</code>

QuerySet如果跨表查詢呢?

我們知道對象跨表查詢可以用點,QuerySet可以使用雙下劃線“__”,例如擷取Uhost表中所有對象的project id 和project name,可以這樣做:

<code>&gt;&gt;&gt; host2 = Uhost.objects.all().values(</code><code>'ip'</code><code>,</code><code>'name'</code><code>,</code><code>'project__id'</code><code>,</code><code>'project__name'</code><code>)</code>

<code>&gt;&gt;&gt; host2[0]</code>

<code>{</code><code>'ip'</code><code>: u</code><code>'10.6.13.253'</code><code>, </code><code>'project__name'</code><code>: u</code><code>'CPMS10'</code><code>, </code><code>'name'</code><code>: u</code><code>'dbbackupsyncer2'</code><code>, </code><code>'project__id'</code><code>: u</code><code>'org-81'</code><code>}</code>

總結:查詢集做跨表查詢時,使用雙下劃線"__"

本文轉自 曾哥最愛 51CTO部落格,原文連結:http://blog.51cto.com/zengestudy/1933826,如需轉載請自行聯系原作者