day19-一对多跨表操作的三种方式
一、前言
我们今天来说说跨表操作,获取数据的三种方式,其实第一种我们已经见识到了,但是还有其他两种方式,那另外两种方式的是如何取另外一张表里面的数据的。
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的类中字段)