1

リリースされた音楽アルバムのデータベースを作成しています

models.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 %}

問題は、アルバムが同じカバー アートで複数回リリースされている場合があることです。その場合、関連するリリースをリストするテキストとともに、画像を 1 回だけ表示したいと考えています。

私はもう試した:

{% 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

アルバムモデルの新しい方法でこれを管理しました。

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

私がこの権利を理解していれば:

  • アルバムには複数のリリースを含めることができます
  • リリースのカバーは 1 つだけです
  • アルバムのすべてのカバーをループしたい

その場合、以下が機能するはずです。

{% 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()

3 番目の方法は、アルバムのカスタム テンプレート フィルターを作成して、すべての個別のリリース カバーを返すことです。

いずれにせよ、Django シェルでそのようなものをデバッグすることをお勧めします。でシェルを発行できます./manage.py shelldjango-extensionsをインストールしている場合は、./manage.py shell_plusすべてのモデルを自動ロードするために使用することもできます。引数を必要としないすべてのオブジェクト属性と関数 (例: 通常のインスタンス属性または のような引数のないインスタンス関数'string'.isalnum()) も、テンプレート内で同じように (かっこなしで) 使用できます。

于 2012-04-10T22:06:03.160 に答える