【发布时间】:2018-06-17 11:27:19
【问题描述】:
我有两个基础模型 SiteData 和 Showoroom Service,它们的模型结构如下所示。
我需要 SiteData 信息,但如果有匹配的 ID,我还想从 showroomservice 模型中获取 link_type。
到目前为止,我尝试了一些事情,但都没有得到我需要的东西,实现这一目标的最佳方法是什么?
谢谢
选择相关
>>> nd = ShowroomService.objects.select_related('site').all()
>>> nd
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/usr/local/lib/python3.6/site-packages/django/db/models/query.py", line 229, in __repr__
return '<%s %r>' % (self.__class__.__name__, data)
File "/usr/local/lib/python3.6/site-packages/django/db/models/base.py", line 590, in __repr__
u = six.text_type(self)
TypeError: __str__ returned non-string (type SiteData)
结合:
>>> complete_data = site_data | monitoring_data
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/usr/local/lib/python3.6/site-packages/django/db/models/query.py", line 310, in __or__
combined.query.combine(other.query, sql.OR)
File "/usr/local/lib/python3.6/site-packages/django/db/models/sql/query.py", line 529, in combine
"Cannot combine queries on two different base models."
AssertionError: Cannot combine queries on two different base models.
链接
>>> final_data = chain(monitoring_data, site_data)
>>> for i in final_data:
... '{} {}'.format(i.location,i.link_Type)
...
Traceback (most recent call last):
File "<console>", line 2, in <module>
AttributeError: 'ShowroomService' object has no attribute 'location'
sites.models.py
class SiteData(models.Model):
location = models.CharField(max_length=50)
site_type = models.ForeignKey(SiteTypes, verbose_name="Site Type", \
on_delete=models.PROTECT)
subnet = models.GenericIPAddressField(protocol='IPv4')
routed_subnet = models.GenericIPAddressField(protocol='IPv4', \
verbose_name="Routed Link Subnet", blank=True, null=True)
bgp_as = models.CharField(max_length=6, verbose_name="BGP AS Number")
opening_date = models.DateField(verbose_name="Showroom opening date")
last_hw_refresh_date = models.DateField(verbose_name="Date of latest hardware refresh", \
blank=True, null=True)
is_live = models.BooleanField(default=False, verbose_name="Is this a live site?")
tel = models.CharField(max_length=20, blank=True, null=True)
address = models.CharField(max_length=255, blank=True, null=True)
town = models.CharField(max_length=255, blank=True, null=True)
...
class Meta:
verbose_name = "Site Data"
verbose_name_plural = "Site Data"
ordering = ('location',)
permissions = (
("can_view", "Can View"),
("can_view_mgmt", "Can View Management"),
)
def __str__(self):
return self.location
monitoring.models.py
from sites.models import SiteData
class ShowroomService(models.Model):
site = models.ForeignKey(SiteData, verbose_name="Site", \
on_delete=models.PROTECT)
link_type = models.CharField(max_length=200, blank=True, null=True)
preference = models.CharField(max_length=200, blank=True, null=True)
timestamp = models.DateTimeField(auto_now_add=True, blank=True, null=True)
dashboard = models.BooleanField(default=True, verbose_name="display on monitoring dashboard?")
class Meta:
verbose_name = "Showroom Service Data"
verbose_name_plural = "Showroom Service Data"
def __str__(self):
return self.site
【问题讨论】:
-
只是为了确保我理解正确的问题,您有一个 SiteData 模型列表,并且您想向后跟踪外键并获取所有子 ShowroomService 记录?
-
您的第一个错误与您的问题无关,但正如消息所述,因为您返回的是 Site 对象,而不是来自
__str__方法的字符串。 -
是的,我想在模板中显示所有站点数据信息以及来自 showroomservice 的链接类型。当我在模板中使用集合时,查看调试工具栏时,由于 set 命令,我正在运行 90 多个查询,因此我想在将它们发送到模板之前将它们组合起来以保存查询
-
所以你试图避免使用我在答案中发布的
*_set属性? -
是的,该集合正在运行 90 多个查询(每个站点一个),这似乎非常低效,我想如果我得到这两个表,我可以在 site.id 上加入它们并改为在两个表中执行90