1

Ich mache eine Datenbank veröffentlicht Musikalbendjango erhalten Liste von verschiedenen ‚Kinder‘ von ForeignKey bezogenen Modell (und tun dies in Vorlage?)

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) 

In meiner Vorlage (im Moment ist ich mit generic views) ich habe:

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

Das Problem ist, dass manchmal ein Album mehrmals mit identischem Cover freigegeben wurde, wobei in diesem Fall ich mag würde das Bild anzuzeigen, nur einmal, wi einen Text, der die Veröffentlichungen auflistet, auf die es sich bezieht.

Ich habe versucht:

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

Oder in einem einfacheren Fall, würde ich zumindest wie die Bilder kleiner anzuzeigen, wenn es mehr als eine von ihnen ist.

Ist es möglich, eine Liste von verwandten Objekten zu erhalten, indem Sie diese ForeignKey-Abfrage umkehren und dann nach dem Satz ihrer Kinder fragen? Der einzige Weg, den ich mir vorstellen kann, besteht darin, einige Tupel/Listen in der Ansicht zusammenzustellen.

Antwort

4

ich es geschafft, diese mit einer neuen Methode auf dem Modell 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 

Dann wird die Vorlage ist viel einfacher:

{% for i in a.distinct_cover_images %} 

Kredit jedoch für seinen Beitrag zu diesem Code @danilobargen.

+0

Ah, natürlich, das ist mir irgendwie entfallen :) Gute Lösung. –

+0

Große Antwort ... Gute Idee, aber ich habe ein Problem mit meiner Implementierung. Meine 'ForeginKey'-Beziehung bezieht sich auf ein anderes Modell in einer anderen App. Ich dachte, das würde immer noch funktionieren, indem ich einfach dieses Modell importiere, aber es sieht so aus, als würde es einen "ImportError" auf beiden Apps auslösen, die an der Beziehung beteiligt sind. Irgendwelche Ideen? – nicorellius

+0

Klingt, als könnte es ein zirkulärer Import sein, insbesondere wenn der Fremdschlüssel in der anderen App definiert ist, weil diese App das Modell bereits von diesem Modul importiert. Hier könnten Sie versuchen, die Import-Anweisung 'from other_app import model' in die Funktionsdefinition zu verschieben, d. H. In die Zeile unter def distinct_cover_images (self)' – nimasmi

2

Wenn ich das richtig verstanden:

  • Ein Album kann mehrere Versionen haben
  • A-Release nur eine Abdeckung
  • Sie über alle Abdeckungen eines Albums Schleife wollen

In diesem Fall sollte Folgendes funktionieren:

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

Wenn Sie verhindern möchten, dass identische Cover aufgelistet werden, können Sie entweder die Cover in der Schleife vergleichen oder ein Set mit verschiedenen Covern in Ihrer Ansicht vorbereiten, damit Sie es an die Vorlage weitergeben können.

Eine dritte Alternative wäre die Erstellung eines benutzerdefinierten Vorlagenfilters für Ihr Album, um alle verschiedenen Release-Cover zurückzugeben.

In jedem Fall empfehle ich, solche Dinge in Ihrer Django-Shell zu debuggen. Sie können die Shell mit ./manage.py shell ausgeben. Wenn Sie django-extensions installiert haben, können Sie auch ./manage.py shell_plus verwenden, um alle Modelle automatisch zu laden. Alle Objektattribute und -funktionen, für die keine Argumente erforderlich sind (z. B. normale Instanzattribute oder Instanzfunktionen ohne Argumente wie 'string'.isalnum()), können ebenfalls (ohne Klammern) in Ihrer Vorlage verwendet werden.

+0

Ja, tut mir leid, ich hätte klarer sein sollen: Ich habe bereits eine funktionierende Forloop mit .Es ist die Entfernung von Duplikaten, nach denen ich suche. – nimasmi

+0

@nimasmi sehe meine Bearbeitung mit dem Beispiel für eine mögliche Lösung. –

+0

@nimasmi Ich habe gerade meine Antwort mit einer anderen Lösung bearbeitet, die die Verwendung von Listen-Comprehensions und dem Set verhindert. –