1

我正在制作一个已发行音乐专辑的数据库

模型.py

class Image(models.Model):
    image = models.ImageField(....

class Album(models.Model):
    title = models.CharField(....

class Release(models.Model):
    album = models.ForeignKey(Album)
    cover_art = models.ForeignKey(Image, blank=True, null=True, on_delete=models.SET_NULL)

在我的模板中(目前我正在使用通用视图)我有:

{% for a in album_list %}
    {% for r in a.release_set.all %}
        {% if r.cover_art %}
        # display cover art image
        {% endif %}
    {% endfor %}
{% endfor %}

问题是,有时一张专辑已经发行了好几次,封面都是一样的,在这种情况下,我只想显示一次图片,并附上一些文字列出它所属的发行版。

我试过了:

{% for i in a.release_set.cover_art %}
{% for i in a.release_set.cover_art_set %}
{% for i in a.release_set.all.cover_art %}
{% for i in a.release_set.all.cover_art_set %}

或者在更简单的情况下,如果有多个图像,我至少希望将图像显示得更小。

{% if a.release_set.count > 1 %} # works but displays duplicate images
{% if a.release_set.cover_art_set.count > 1 %} # doesn't work (see above)

是否可以通过反转此 ForeignKey 查找然后询问他们的孩子的集合来获得相关的对象列表?我能想到的唯一方法是在视图中组装一些元组/列表。

4

2 回答 2

4

我在 Album 模型上使用了一种新方法来管理它:

class Album(models.Model):
    title = models.CharField(....

    def distinct_cover_images(self):
        "Returns the queryset of distinct images used for this album cover"
        pks = self.release_set.all().values_list('cover_art__pk', flat=True)
        distinct_cover_images = Images.objects.filter(pk__in=pks).distinct()
        return distinct_cover_images

那么模板就简单多了:

{% for i in a.distinct_cover_images %}

感谢@danilobargen,感谢他对这段代码的贡献。

于 2012-04-11T11:11:29.337 回答
3

如果我理解正确:

  • 一张专辑可以有多个版本
  • 发行版只有一个封面
  • 您想遍历专辑的所有封面

在这种情况下,以下应该有效:

{% for release in a.release_set.all %}
  {{ release.cover_art.image }}
{% endfor %}

如果您想防止列出相同的封面,您可以比较循环中的封面,或者在您的视图中准备一个具有不同封面的集合,以便您可以将其传递给模板。

# Solution using a set
context['distinct_coverimages'] = \
    set([r.cover_art.image for r in album.release_set.all()])

# Solution using two queries, might perform better
pks = album.release_set.values_list('cover_art__pk', flat=True)
context['distinct_coverimages'] = models.Image.filter(pk__in=pks).distinct()

第三种选择是为您的专辑创建一个自定义模板过滤器,以返回所有不同的发行封面。

无论如何,我建议在你的 Django shell 中调试这些东西。您可以使用./manage.py shell. 如果你已经安装了django-extensions,你也可以使用它./manage.py shell_plus来自动加载所有模型。所有不需要参数的对象属性和函数(例如,普通的实例属性或没有参数的实例函数,如'string'.isalnum())也可以在模板中以相同的方式使用(只是没有括号)。

于 2012-04-10T22:06:03.160 回答