【问题标题】:Django query for linking related data in template用于链接模板中相关数据的 Django 查询
【发布时间】:2013-01-24 20:12:10
【问题描述】:

我在 Django 应用程序中有两个数据表,一个包含船舶详细信息,另一个包含与单个船舶相关的报价。我的模型如下:

class Vessel(models.Model):
    name = models.CharField(max_length=64)
    image = models.CharField(max_length=64)
    vesseltype = models.ForeignKey(VesselType)
    capacity = models.IntegerField()
    length = models.FloatField()
    beam = models.FloatField()
    speed = models.IntegerField()
    activities = models.CharField(max_length=256)
    category = models.IntegerField()
    display_order = models.IntegerField()
    published = models.BooleanField()
    def __unicode__(self):
        return self.name

class Offer(models.Model):
    vessel = models.ForeignKey(Vessel)
    description = models.CharField(max_length=128)
    date = models.DateField()
    duration = models.IntegerField()
    itinerary = models.TextField()
    price = models.IntegerField()
    display_order = models.IntegerField()
    link = models.URLField()
    published = models.BooleanField()
    def __unicode__(self):
        return self.description

在我的views.py中我有以下代码:

def home(request):
    vessels = Vessel.objects.filter(published='y').order_by('display_order')
    offers = Offer.objects.filter(vessel__published__exact='y').filter(published='y').order_by('display_order')
    t = loader.get_template('index.html')
    c = Context({
        'vessels' : vessels,
        'offers' : offers,
    })

在模板中,我需要显示多个 div,每个 div 都包含船只名称、一些船只详细信息以及与该船只相关的任意数量的报价。

我查看了尝试将报价与每艘船只相关联的查询,并且我还尝试在模板中的循环代码内识别船只名称,以便仅在vessel.id 和 offer.vessel 匹配时显示报价.

到目前为止,仅在查询端出现错误并通过模板方式单独列出船只名称和报价,都没有成功。如何加入这些信息,以便我可以在模板中使用类似的内容:

for offer in offers:
    offer.vessel.name
    offer.vessel.category
    offer.description
    offer.price

还是我期望过高?一直在这几个小时,无法在文档中找到解决方案,但这可能很明显。更改查询、视图代码或模板都不是问题。

【问题讨论】:

  • 您已经可以完全按照您的示例代码所示进行操作(一旦您将引用包装在模板标记语法中)。不过,Garry Cairns 的回答会让事情变得更有效率。
  • 抱歉缺少模板标签,这只是为了展示我试图实现的伪代码。使用上面的代码,我可以访问 offer.description 和 offer.price,但是当我尝试使用 offer.vessel.name 时,我不断收到关于没有属性名称的错误。但是,可以通过vessel.name 访问名称,因此不确定那里发生了什么。检查我的代码以确保它与我在上面输入的相同。

标签: django templates join models


【解决方案1】:

答案是更改您的view 代码。你想要一个像Offer.objects.all().select_related() 这样的查询集。 select_related 将确保您不会在每次循环执行时都访问数据库,因为它会在执行查询之前跟随外键到末尾。

您还使用了错误的template syntax。它需要是这样的:

{% for object in object_list %}
{{ object.attribute }}
{% endfor %}

【讨论】:

  • 谢谢加里,效果很好。我跟踪了 Django 文档周围的链接,试图找到类似的东西,但没有一个以 select_related 结尾。
  • 重申一下,外键对象引用语法不需要select_related(),它只是通过避免每行额外的db调用来提高效率。
猜你喜欢
  • 2011-06-22
  • 1970-01-01
  • 2018-09-13
  • 1970-01-01
  • 2023-01-31
  • 2021-07-06
  • 2015-01-29
  • 2021-10-04
  • 1970-01-01
相关资源
最近更新 更多