我在django的moles中创建了两个calss,如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
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表中的第一个对象
1
2
3
|
>>> host
=
Uhost.objects.
all
()[
0
]
>>>
print
type
(host)
<
class
'ucloud.models.Uhost'
>
|
对象获取某个值使用“.”
例如:
1
2
3
4
5
6
|
>>> host.
id
u
'uhost-3th2rp'
>>> host.ip
u
'10.6.13.253'
>>> host.project
<Project: CPMS10>
|
注意:Uhost表中project字段是一个ForeighKey,当获取host.project时,获取到的结果是一个对象
我们还可以获取这个对象其他值,比如Project表中定义了name、id、create_time、update_time四个字段,我们可以通过下面的方式获取
1
2
3
4
5
6
7
8
|
>>> 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值还可以使用下面这种方式获取:
1
2
3
4
5
6
|
>>> 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这个字段的值是因为,在Uhost表中project字段是ForeignKey,而在数据库中被设置了外键的列,在数据库中的字段名就是本表中的列名 +“_“”+被设置外键的表的那个字段名,而Project表中id是primary_key,所以id列被设置了外键 。
由上可知,host.project.id是跨表查询,而host.project_id并不是跨表查询。因为这个字段在自己表中。
QuerySet查询集:
查询集是一组数据的集合,跟python的list基本一样的。例如获取以下方法可以获取Uhost表中所有对象的ip和name。
1
2
3
4
|
>>> 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如果跨表查询呢?
我们知道对象跨表查询可以用点,QuerySet可以使用双下划线“__”,例如获取Uhost表中所有对象的project id 和project name,可以这样做:
1
2
3
|
>>> 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'
}
|
总结:查询集做跨表查询时,使用双下划线"__"