Python Django-在两个不同的基础模型上选择相关或联接

Python Django-在两个不同的基础模型上选择相关或联接,python,django,Python,Django,我有两个基本模型SiteData和Showoroom服务,其模型结构如下所示 我需要站点数据信息,但如果有匹配的ID,我也想从showroomservice模型中获取链接类型 到目前为止,我尝试了一些事情,但没有一件能得到我所需要的,实现这一点的最佳方法是什么 谢谢 选择相关 >>> nd = ShowroomService.objects.select_related('site').all() >>> nd Traceback (most recent c

我有两个基本模型SiteData和Showoroom服务,其模型结构如下所示

我需要站点数据信息,但如果有匹配的ID,我也想从showroomservice模型中获取链接类型

到目前为止,我尝试了一些事情,但没有一件能得到我所需要的,实现这一点的最佳方法是什么

谢谢

选择相关

>>> 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)
monitoring.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
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

您可以使用django的“相关管理器”提取所有相关对象。文件可在以下位置获得:

通过在
SiteData
模型上调用
showroom\u service\u set
,您可以获得每个
SiteData
的子记录集

为了解释为什么列出的尝试也失败了:

  • 模型上的
    \uuu str\uu
    方法需要返回字符串。如果他们不这样做,你会得到例外
  • 管道操作符
    |
    用于在django中将查询
    组合在一起。这段代码正试图组合两种不同类型模型的查询
  • 通过链尝试,您已经创建了一个包含两种不同类型模型的列表。其中一个没有
    位置
    属性
  • 下面是一段代码,用于获取连接到SiteData模型的所有ShowroomService模型的链接类型:

    for site_data in SiteData.objects.all():
        for showroom in site_data.showroom_service_set.all():
            print showroom.link_type
    
    我不确定django如何处理相关对象的骆驼壳,所以我最好的猜测是
    showroom\u service\u set
    。您可能需要对此进行一些腿部工作,以了解实际集合的名称


    编辑:有一种叫做预回迁的东西。这里有一个很好的答案;我想它会满足您的需求:

    您可以使用django的“相关管理器”提取所有相关对象。文件可在以下位置获得:

    通过在
    SiteData
    模型上调用
    showroom\u service\u set
    ,您可以获得每个
    SiteData
    的子记录集

    为了解释为什么列出的尝试也失败了:

  • 模型上的
    \uuu str\uu
    方法需要返回字符串。如果他们不这样做,你会得到例外
  • 管道操作符
    |
    用于在django中将查询
    组合在一起。这段代码正试图组合两种不同类型模型的查询
  • 通过链尝试,您已经创建了一个包含两种不同类型模型的列表。其中一个没有
    位置
    属性
  • 下面是一段代码,用于获取连接到SiteData模型的所有ShowroomService模型的链接类型:

    for site_data in SiteData.objects.all():
        for showroom in site_data.showroom_service_set.all():
            print showroom.link_type
    
    我不确定django如何处理相关对象的骆驼壳,所以我最好的猜测是
    showroom\u service\u set
    。您可能需要对此进行一些腿部工作,以了解实际集合的名称


    编辑:有一种叫做预回迁的东西。这里有一个很好的答案;我想这会帮你找到你想要的:

    为了确保我正确理解这个问题,你有一个SiteData模型列表,并且你想按照外键向后移动,获取所有子ShowroomService记录?你的第一个错误与你的问题无关,但正如消息所述,这是因为您从
    \uuuu str\uuuu
    方法返回的是站点对象而不是字符串。是的,在模板中,我希望显示所有站点数据信息以及showroomservice中的链接类型。当我在模板中使用集合时,查看调试工具栏,我正在运行90多个查询,因为使用了set命令,所以我想在将它们发送到模板之前将它们组合起来以保存查询,所以您试图避免使用我在回答中发布的
    *\u set
    属性?是的,集合正在运行90多个查询(每个站点一个)这似乎效率很低,我想如果我得到这两个表,我可以在site.id上连接它们,并在两个表中而不是90个表中进行连接,以确保我正确理解问题,您有一个SiteData模型列表,并且希望按照外键向后移动并获取所有子ShowroomService记录?您的第一个错误与您的问题无关,但正如消息所述,这是因为您从
    \uuu str\uuu
    方法返回的是站点对象而不是字符串。是的,在模板中,我想显示所有站点数据信息以及showroomservice中的链接类型。当我在模板中使用集合时,查看调试工具栏,我正在运行90多个查询,因为使用了set命令,所以我想在将它们发送到模板之前将它们组合起来以保存查询,所以您试图避免使用我在回答中发布的
    *\u set
    属性?是的,集合正在运行90多个查询(每个站点一个)这似乎效率很低,我想如果我得到这两个表,我可以在site.id上连接它们,并在两个表中执行,而不是90个与预取相关的操作,在29毫秒内执行6个查询,而不是现在150毫秒内执行100个查询:)与预取相关的操作,在29毫秒内执行6个查询,而不是现在150毫秒内执行100个查询:)
    for site_data in SiteData.objects.all():
        for showroom in site_data.showroom_service_set.all():
            print showroom.link_type