如何在Django中选择特定的相关元素?

时间:2014-02-18 10:43:20

标签: django django-select-related

我有一个名为'Projects'的模型。

可以展示项目。如果是,它们将显示在主页上 (Projects.filter(is_featured = TRUE))

每个项目都包含几张幻灯片。这些幻灯片可以是特色(Slide.is_featured = True),并包含一个包含实际图像的图像模型。

在我的主页中,我想显示幻灯片,其中每张幻灯片包含项目名称和特色幻灯片中包含的图像。

我通过在我的项目模型中添加一个名为'featured_slide()'的方法来做到这一点,但现在我意识到我每次都在使用数据库,我希望通过使用'select_related'来改进它言。

我该怎么做?

最理想的情况是,我希望有一个像'featured_slide'这样的字段来代表特色幻灯片。

我正在考虑按照以下方式做点什么:

Projects.filter(is_featured=True).annotate(featured_slide='slides__is_featured=True').select_related(slides__image)

我知道它不能那么简单(slides__is_featured不是数据库字段),但你明白了。

1 个答案:

答案 0 :(得分:2)

如果您想要仅展示自己特色的Slides幻灯片以及与精选Projects相关的幻灯片:

class Project(...):
    name = models.CharField()
    is_featured = models.BooleanField()

class Slide(...):
    project = models.ForeignKey(Project)
    is_featured = models.BooleanField()
    image = models.ImageField()

查询幻灯片(使用select_related以避免不必要的查询):

slides = Slide.select_related("project").filter(is_featured=True, project__is_featured=True)

和模板:

<ul>
    {% for slide in slides %}
         <li><img src="{{ slide.image.url }} /><span class="caption">{{ slide.project.name }}</caption></li>
    {% endfor %}
</ul>

修改

如果您要查找reverse relationship(即获取项目的所有幻灯片),默认情况下您可以执行以下操作:

project = Project.objects.get(...)
project_slides = project.slide_set.all()

您将_set添加到模型名称。您可以通过在关系中添加related_name属性来使此更直观:

class Slide(...):
    project = models.ForeignKey(Project, related_name="slideshow_slides")

现在使用:

project = Project.objects.get(...)
project.slideshow_slides.all()