天天看点

Django 多表联合查询

一对多的表查询

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

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

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

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

<code>    </code><code>create_date </code><code>=</code> <code>models.DateTimeField(u</code><code>'创建时间'</code><code>, auto_now_add</code><code>=</code><code>True</code><code>)</code>

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

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

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

<code>        </code> 

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

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

<code>    </code><code>id</code> <code>=</code> <code>models.CharField(u</code><code>'实例ID'</code><code>,max_length</code><code>=</code><code>32</code><code>,blank</code><code>=</code><code>False</code><code>,primary_key</code><code>=</code><code>True</code><code>)</code>

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

<code>    </code><code>cpu </code><code>=</code> <code>models.CharField(u</code><code>'CPU/核'</code><code>,max_length</code><code>=</code><code>32</code><code>,blank</code><code>=</code><code>True</code><code>,null</code><code>=</code><code>True</code><code>)</code>

<code>    </code><code>memory </code><code>=</code> <code>models.CharField(U</code><code>'内存/G'</code><code>,max_length</code><code>=</code><code>32</code><code>,blank</code><code>=</code><code>True</code><code>)</code>

<code>    </code><code>state </code><code>=</code> <code>models.CharField(u</code><code>'实例状态'</code><code>,max_length</code><code>=</code><code>32</code><code>,blank</code><code>=</code><code>True</code><code>)</code>

<code>    </code><code>expiretime </code><code>=</code> <code>models.DateTimeField(u</code><code>'到期时间'</code><code>, max_length</code><code>=</code><code>50</code><code>, null</code><code>=</code><code>True</code><code>, blank</code><code>=</code><code>True</code><code>)</code>

<code>    </code><code>isexpire </code><code>=</code> <code>models.CharField(u</code><code>'是否过期'</code><code>, max_length</code><code>=</code><code>20</code><code>, blank</code><code>=</code><code>True</code><code>)</code>

<code>    </code><code>autorenew </code><code>=</code> <code>models.CharField(u</code><code>'自动续费'</code><code>, max_length</code><code>=</code><code>20</code><code>, blank</code><code>=</code><code>True</code><code>)</code>

<code>    </code><code>tag </code><code>=</code> <code>models.CharField(u</code><code>'业务组'</code><code>,max_length</code><code>=</code><code>32</code><code>,blank</code><code>=</code><code>True</code><code>)</code>

<code>    </code><code>networkstate </code><code>=</code> <code>models.CharField(u</code><code>'网络状态'</code><code>,max_length</code><code>=</code><code>32</code><code>,blank</code><code>=</code><code>True</code><code>)</code>

<code>    </code><code>type</code> <code>=</code> <code>models.CharField(u</code><code>'实例类型'</code><code>,max_length</code><code>=</code><code>32</code><code>,blank</code><code>=</code><code>True</code><code>)</code>

<code>    </code><code>osfamily </code><code>=</code> <code>models.CharField(u</code><code>'系统类型'</code><code>,max_length</code><code>=</code><code>32</code><code>,blank</code><code>=</code><code>True</code><code>)</code>

<code>    </code><code>ostype </code><code>=</code> <code>models.CharField(u</code><code>'操作系统'</code><code>, max_length</code><code>=</code><code>50</code><code>, blank</code><code>=</code><code>True</code><code>)</code>

<code>    </code><code>chargetype </code><code>=</code> <code>models.CharField(u</code><code>'付费类型'</code><code>, max_length</code><code>=</code><code>50</code><code>, blank</code><code>=</code><code>True</code><code>)</code>

<code>    </code><code>datadisk </code><code>=</code> <code>models.IntegerField(u</code><code>'数据盘/G'</code><code>, blank</code><code>=</code><code>True</code><code>)</code>

<code>    </code><code>price </code><code>=</code> <code>models.DecimalField(u</code><code>'价格'</code><code>,max_digits</code><code>=</code><code>8</code><code>,decimal_places</code><code>=</code><code>2</code><code>,null</code><code>=</code><code>True</code><code>,blank</code><code>=</code><code>True</code><code>)</code>

<code>    </code><code>zone </code><code>=</code> <code>models.ForeignKey(Zone,verbose_name</code><code>=</code><code>u</code><code>'可用区'</code><code>,db_constraint</code><code>=</code><code>False</code><code>,on_delete</code><code>=</code><code>models.DO_NOTHING,blank</code><code>=</code><code>True</code><code>)</code>

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

我建了两张表,project和uhost。

其中uhost表的project字段是设置了ForeignKey。

先看下project表中的内容。

<code>&gt;&gt;&gt; Project.objects.</code><code>all</code><code>()</code>

<code>[&lt;Project: 上海别样红信息技术有限公司&gt;, &lt;Project: 备案专用&gt;, &lt;Project: gitlab&gt;, </code>

<code>&lt;Project: PublicTest&gt;, &lt;Project: SPMS&gt;, &lt;Project: 安全测试&gt;, &lt;Project: OTA&gt;, </code>

<code>&lt;Project: </code><code>99</code><code>数据同步中转,本项目与</code><code>99</code><code>内网打通,不允许添加任何机器&gt;, &lt;Project: Ops&gt;,</code>

<code> </code><code>&lt;Project: iPms&gt;]</code>

<code>&gt;&gt;&gt; Project.objects.</code><code>all</code><code>().values(</code><code>'id'</code><code>)</code>

<code>[{</code><code>'id'</code><code>: u</code><code>'org-81'</code><code>}, {</code><code>'id'</code><code>: u</code><code>'org-aws3dj'</code><code>}, {</code><code>'id'</code><code>: u</code><code>'org-et55qg'</code><code>}, </code>

<code>{</code><code>'id'</code><code>: u</code><code>'org-ghan2t'</code><code>}, {</code><code>'id'</code><code>: u</code><code>'org-ja1wvv'</code><code>}, {</code><code>'id'</code><code>: u</code><code>'org-kbxrx4'</code><code>}, </code>

<code>{</code><code>'id'</code><code>: u</code><code>'org-pni2a2'</code><code>}, {</code><code>'id'</code><code>: u</code><code>'org-qf4d2n'</code><code>}, {</code><code>'id'</code><code>: u</code><code>'org-vzfixt'</code><code>}, </code>

<code>{</code><code>'id'</code><code>: u</code><code>'org-wrg10n'</code><code>}]</code>

表查询:

查询uhost表中name中包含OPS10的所有主机对象

<code>&gt;&gt;&gt; Uhost.objects.</code><code>filter</code><code>(name__contains</code><code>=</code><code>'OPS10'</code><code>)</code>

<code>[&lt;Uhost: SRV</code><code>-</code><code>OPS10</code><code>-</code><code>CS05&gt;, &lt;Uhost: SRV</code><code>-</code><code>OPS10</code><code>-</code><code>SPPX01&gt;, &lt;Uhost: SRV</code><code>-</code><code>OPS10</code><code>-</code><code>MAIL01&gt;, </code>

<code>&lt;Uhost: SRV</code><code>-</code><code>OPS10</code><code>-</code><code>PROXY02&gt;, &lt;Uhost: SRV</code><code>-</code><code>OPS10</code><code>-</code><code>PROXY01&gt;, &lt;Uhost: SRV</code><code>-</code><code>OPS10</code><code>-</code><code>HAP02&gt;,</code>

<code> </code><code>&lt;Uhost: SRV</code><code>-</code><code>OPS10</code><code>-</code><code>HAP01&gt;, &lt;Uhost: SRV</code><code>-</code><code>OPS10</code><code>-</code><code>ANSIBLE02&gt;, &lt;Uhost: SRV</code><code>-</code><code>OPS10</code><code>-</code><code>NGX01&gt;, </code>

<code> </code><code>&lt;Uhost: SRV</code><code>-</code><code>OPS10</code><code>-</code><code>NGX02&gt;, &lt;Uhost: SRV</code><code>-</code><code>OPS10</code><code>-</code><code>PROXY05&gt;, &lt;Uhost: SRV</code><code>-</code><code>OPS10</code><code>-</code><code>ANSIBLE06&gt;, </code>

<code> </code><code>&lt;Uhost: SRV</code><code>-</code><code>OPS10</code><code>-</code><code>DEPLOY01&gt;, &lt;Uhost: SRV</code><code>-</code><code>OPS10</code><code>-</code><code>NGINX01&gt;, &lt;Uhost: SRV</code><code>-</code><code>OPS10</code><code>-</code><code>ES02&gt;, </code>

<code> </code><code>&lt;Uhost: SRV</code><code>-</code><code>OPS10</code><code>-</code><code>ES03&gt;, &lt;Uhost: SRV</code><code>-</code><code>OPS10</code><code>-</code><code>ES01&gt;, &lt;Uhost: SRV</code><code>-</code><code>OPS10</code><code>-</code><code>LOGSTASH01&gt;, </code>

<code> </code><code>&lt;Uhost: SRV</code><code>-</code><code>OPS10</code><code>-</code><code>PROXY04&gt;, &lt;Uhost: SRV</code><code>-</code><code>OPS10</code><code>-</code><code>PROXY03&gt;, </code><code>'...(remaining elements truncated)...'</code><code>]</code>

正向查询:

若关系模型A包含与模型B关联的关联字段, 模型A的实例可以通过关联字段访问与其关联的模型B的实例:

Django提供了一种使用双下划线<code>__</code>的查询语法:

例如:

<code>Uhost.objects.</code><code>filter</code><code>(project__id</code><code>=</code><code>'org-81'</code><code>)</code>

查找uhost表中,所有project id为‘org-81’的的主机

<code>&gt;&gt;&gt; Uhost.objects.</code><code>filter</code><code>(project__id</code><code>=</code><code>'org-81'</code><code>)</code>

<code>[&lt;Uhost: dbbackupsyncer2&gt;, &lt;Uhost: SRV</code><code>-</code><code>CPMS10</code><code>-</code><code>WEB16&gt;, &lt;Uhost: SRV</code><code>-</code><code>CPMS10</code><code>-</code><code>WEB15&gt;, </code>

<code>&lt;Uhost: publicconsole&gt;, &lt;Uhost: SRV</code><code>-</code><code>CPMS10</code><code>-</code><code>WEB14&gt;, &lt;Uhost: dbbackupsyncer&gt;,</code>

<code>&lt;Uhost: 官网&gt;, &lt;Uhost: </code><code>99exchangedb</code><code>&gt;, &lt;Uhost: dc1&gt;, &lt;Uhost: dc2&gt;, &lt;Uhost: publicweb&gt;, </code>

<code>&lt;Uhost: SRV</code><code>-</code><code>CPMS10</code><code>-</code><code>WEB13&gt;, &lt;Uhost: SRV</code><code>-</code><code>OTA10</code><code>-</code><code>WS04&gt;, &lt;Uhost: SRV</code><code>-</code><code>OTA10</code><code>-</code><code>WS05&gt;, </code>

<code>&lt;Uhost: SRV</code><code>-</code><code>OPS10</code><code>-</code><code>CS05&gt;, &lt;Uhost: SRV</code><code>-</code><code>OTA10</code><code>-</code><code>WS03&gt;, &lt;Uhost: SRV</code><code>-</code><code>OTA10</code><code>-</code><code>WEB04&gt;, </code>

<code>&lt;Uhost: SRV</code><code>-</code><code>OTA10</code><code>-</code><code>WEB03&gt;, &lt;Uhost: </code><code>99datasyncer</code><code>&gt;, &lt;Uhost: SRV</code><code>-</code><code>CPMS10</code><code>-</code><code>WEB31&gt;, </code><code>'...(remaining elements truncated)...'</code><code>]</code>

查询uhost表中project id包含‘ghan’的主机信息

<code>&gt;&gt;&gt; Uhost.objects.</code><code>filter</code><code>(project__id__contains</code><code>=</code><code>'ghan'</code><code>)</code>

<code>[&lt;Uhost: SRV</code><code>-</code><code>OPS10</code><code>-</code><code>ANSIBLE06&gt;, &lt;Uhost: SRV</code><code>-</code><code>OPS10</code><code>-</code><code>DEPLOY01&gt;, \</code>

<code>&lt;Uhost: SRV</code><code>-</code><code>OPS01</code><code>-</code><code>DEPLOY01&gt;, &lt;Uhost: SRV</code><code>-</code><code>OPS10</code><code>-</code><code>NGINX01&gt;, \</code>

<code>&lt;Uhost: SRV</code><code>-</code><code>OPS10</code><code>-</code><code>ES02&gt;, &lt;Uhost: SRV</code><code>-</code><code>OPS10</code><code>-</code><code>ES03&gt;, &lt;Uhost: SRV</code><code>-</code><code>OPS10</code><code>-</code><code>ES01&gt;,\</code>

<code>&lt;Uhost: SRV</code><code>-</code><code>OPS10</code><code>-</code><code>LOGSTASH01&gt;]</code>

反向查询:

被索引的关系模型可以访问所有参照它的模型的实例,如Entry.blog作为Blog的外键,默认情况下Blog.entry_set是包含所有参照Blog的Entry示例的查询集,可以使用查询集API取出相应的实例。

查询project name为Ops的所有主机对象

<code>&gt;&gt;&gt; Project.objects.get(name</code><code>=</code><code>'Ops'</code><code>).uhost_set.</code><code>all</code><code>()</code>

<code>[&lt;Uhost: SRV</code><code>-</code><code>OPS10</code><code>-</code><code>ANSIBLE06&gt;, &lt;Uhost: SRV</code><code>-</code><code>OPS10</code><code>-</code><code>DEPLOY01&gt;,</code>

<code>&lt;Uhost: SRV</code><code>-</code><code>OPS01</code><code>-</code><code>DEPLOY01&gt;, &lt;Uhost: SRV</code><code>-</code><code>OPS10</code><code>-</code><code>NGINX01&gt;, </code>

<code>&lt;Uhost: SRV</code><code>-</code><code>OPS10</code><code>-</code><code>ES02&gt;, &lt;Uhost: SRV</code><code>-</code><code>OPS10</code><code>-</code><code>ES03&gt;, &lt;Uhost: SRV</code><code>-</code><code>OPS10</code><code>-</code><code>ES01&gt;, </code>

查询project name为Ops的所有主机对象的name属性

<code>&gt;&gt;&gt; Project.objects.get(name</code><code>=</code><code>'Ops'</code><code>).uhost_set.values(</code><code>'name'</code><code>)</code>

<code>[{</code><code>'name'</code><code>: u</code><code>'SRV-OPS10-ANSIBLE06'</code><code>}, {</code><code>'name'</code><code>: u</code><code>'SRV-OPS10-DEPLOY01'</code><code>}, \</code>

<code>{</code><code>'name'</code><code>: u</code><code>'SRV-OPS01-DEPLOY01'</code><code>}, {</code><code>'name'</code><code>: u</code><code>'SRV-OPS10-NGINX01'</code><code>}, \</code>

<code>{</code><code>'name'</code><code>: u</code><code>'SRV-OPS10-ES02'</code><code>}, {</code><code>'name'</code><code>: u</code><code>'SRV-OPS10-ES03'</code><code>}, \</code>

<code>{</code><code>'name'</code><code>: u</code><code>'SRV-OPS10-ES01'</code><code>}, {</code><code>'name'</code><code>: u</code><code>'SRV-OPS10-LOGSTASH01'</code><code>}]</code>

查询project name为Ops的,并且name包含OPS字符串的所有主机

<code>&gt;&gt;&gt; Project.objects.get(name</code><code>=</code><code>'Ops'</code><code>).uhost_set.</code><code>filter</code><code>(name__contains</code><code>=</code><code>'OPS'</code><code>)</code>

<code>[&lt;Uhost: SRV</code><code>-</code><code>OPS10</code><code>-</code><code>ANSIBLE06&gt;, &lt;Uhost: SRV</code><code>-</code><code>OPS10</code><code>-</code><code>DEPLOY01&gt;, </code>

一对多表创建对象:

<code>&gt;&gt;&gt; host</code><code>=</code><code>Uhost(</code><code>id</code><code>=</code><code>'aaaaa'</code><code>)</code>

<code>&gt;&gt;&gt; host.project</code><code>=</code><code>Project.objects.get(</code><code>id</code><code>=</code><code>'org-81'</code><code>)</code>

<code>&gt;&gt;&gt; host</code><code>=</code><code>Uhost(name</code><code>=</code><code>'SRV-TEST'</code><code>)</code>

<code>&gt;&gt;&gt; host.save()</code>

多对多的查询

示例:

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

<code>    </code><code>name </code><code>=</code> <code>models.CharField(U</code><code>'组名'</code><code>,max_length</code><code>=</code><code>32</code><code>,blank</code><code>=</code><code>True</code><code>)</code>

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

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

<code>    </code><code>email </code><code>=</code> <code>models.EmailField(u</code><code>'邮箱'</code><code>)</code>

<code>    </code><code>group </code><code>=</code> <code>models.ManyToManyField(GroupInfo)</code>

<a href="https://s5.51cto.com/wyfs02/M01/8E/9A/wKiom1jGdRehFUyoAAGnqu-0Nns885.png" target="_blank"></a>

<a href="https://s5.51cto.com/wyfs02/M02/8E/A2/wKioL1jHl0Wh-ai7AABc2BMow3M250.png" target="_blank"></a>

<a href="https://s3.51cto.com/wyfs02/M01/8E/A4/wKiom1jHl0bCyrzrAABtjlsZJro099.png" target="_blank"></a>

查询:

从userinfo表开始查

<code>&gt;&gt;&gt; UserInfo.objects.get(name</code><code>=</code><code>'zeng'</code><code>).group.</code><code>all</code><code>()</code>

<code>[&lt;GroupInfo: 运维组&gt;, &lt;GroupInfo: 报警组&gt;]</code>

<code>&gt;&gt;&gt; UserInfo.objects.get(name</code><code>=</code><code>'zeng'</code><code>).group.</code><code>filter</code><code>(name</code><code>=</code><code>'运维组'</code><code>)</code>

<code>[&lt;GroupInfo: 运维组&gt;]</code>

从groupinfo表开始查

<code>&gt;&gt;&gt; GroupInfo.objects.get(name</code><code>=</code><code>'CTO'</code><code>).userinfo_set.</code><code>all</code><code>()</code>

<code>[&lt;UserInfo: zhang&gt;]</code>

<code>&gt;&gt;&gt; GroupInfo.objects.get(name</code><code>=</code><code>'CTO'</code><code>).userinfo_set.values(</code><code>'name'</code><code>,</code><code>'email'</code><code>)</code>

<code>[{</code><code>'name'</code><code>: u</code><code>'zhang'</code><code>, </code><code>'email'</code><code>: u</code><code>'[email protected]'</code><code>}]</code>

多对多表 创建对象:

<code>&gt;&gt;&gt; u </code><code>=</code> <code>UserInfo(name</code><code>=</code><code>'he'</code><code>,email</code><code>=</code><code>'[email protected]'</code><code>)</code>

<code>&gt;&gt;&gt; u.save()</code>

<code>&gt;&gt;&gt; u.group.add(GroupInfo.objects.get(name</code><code>=</code><code>'运维组'</code><code>))</code>

注意:

要添加新对象时,首先必须保证该对象在做ManyToMany的两张表中存在才行,比如上面的例子,我想创建一个叫he的用户,组为运维组。但是he这个用户不存在,所以先必须创建he这个对象,才能给他添加到运维组。

<a href="https://s1.51cto.com/wyfs02/M02/8E/A4/wKiom1jHoKawe8KfAAChgqWrYyk912.png" target="_blank"></a>

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