一、前言
我们今天来说说跨表操作,获取数据的三种方式,其实第一种我们已经见识到了,但是还有其他两种方式,那另外两种方式的是如何取另外一张表里面的数据的。
modles.py的表结构关系如下:
# class Foo(models.Model):
# name = models.CharField(max_length=10)
class Business(models.Model):
caption = models.CharField(max_length=32)
code = models.CharField(max_length=32,default="SA")
# foo = models.ForeignKey('Foo',to_field='id')
class Host(models.Model):
nid = models.AutoField(primary_key=True)
hostname = models.CharField(max_length=32,db_index=True)
ip = models.GenericIPAddressField(protocol='ipv4',db_index=True)
port = models.IntegerField()
business = models.ForeignKey(to="Business",to_field="id",on_delete=models.CASCADE,)
以上可以通过host中的business字段,反射出Foo中的name值:
row.business.foo.name
二、一对多跨表操作的三种方式
2.1、对象获取的方式
说明:我们说一张表里面的外键字段,其实是另外一张表的对象,通过这个对象获取另外一张表的字段的值
from app01 import models
def host(request):
v1 = models.Host.objects.filter(nid__gte=1)
return render(request,"host.html",{'v1':v1})
templates模板引用:
<h1>业务线列表(对象)</h1>
<table border="1">
<thead>
<tr>
<th>主机名</th>
<th>IP</th>
<th>端口</th>
<th>业务线名称</th>
<th>业务线编码</th>
</tr>
</thead>
<tbody>
{% for row in v1 %}
<tr h-id="{{ row.nid }}" b-id="{{ row.business.id }}">
<td>{{ row.hostname }}</td>
<td>{{ row.ip }}</td>
<td>{{ row.port }}</td>
<td>{{ row.business.caption }}</td>
<td>{{ row.business.code }}</td>
</tr>
{% endfor %}
</tbody>
</table>
2.2、以字典的方式
说明:values(),这样就会以字符串的方式取了,所以这边如果跨表获取字段的话,必须需要 两个下划线了,即:business__caption
def host(request):
v2 = models.Host.objects.filter(nid__gt=0).values("nid","hostname","business_id","business__caption") #如果是字符串的话,需要用两个下划线获取对象中的值
print(v2)
return render(request,"host.html",{'v2':v2})
#输出
<QuerySet [{'business_id': 1, 'hostname': 'shabihong', 'nid': 1, 'business__caption': '运维'}]>
templates模板引用:
<h1>业务线列表(字典)</h1>
<table border="1">
<thead>
<tr>
<th>主机名</th>
<th>业务线名称</th>
</tr>
</thead>
<tbody>
{% for row in v2 %}
<tr h-id="{{ row.nid }}" b-id="{{ row.business_id }}">
<td>{{ row.hostname }}</td>
<td>{{ row.business__caption }}</td>
</tr>
{% endfor %}
</tbody>
</table>
2.3、以元组的方式
说明:values_list,获取的跟values差不多,只不过是采用的元组的方式,获取对象中的值,同样是双下划线
def host(request):
v3 = models.Host.objects.filter(nid__gt=0).values_list("nid","hostname","business_id","business__caption")
print(v3)
return render(request,"host.html",{'v3':v3})
templates模板引用:
<h1>业务线列表(元组)</h1>
<table border="1">
<thead>
<tr>
<th>主机名</th>
<th>业务线名称</th>
</tr>
</thead>
<tbody>
{% for row in v3 %}
<tr h-id="{{ row.0 }}" b-id="{{ row.2 }}">
<td>{{ row.1 }}</td>
<td>{{ row.3 }}</td>
</tr>
{% endfor %}
</tbody>
</table>
三、总结
- 通过外键的方式获取另外一张表中的字段值,一个是以对象的方式,一个是以字符串的方式
- 只要遇到 values,values_list的方式获取字符值,需要 外键名__字段名,比如:business__caption(business的是外键名,caption是Business的类中字段)
- 只要是querySet类型的,且是对象的,就需要 外键名.字段名 比如:business.caption(business的是外键名,caption是Business的类中字段)