Odwrotna strona relacji

Przypuśćmy, że projektujemy prosty blog, w którym do każdego wpisu mogą być dołączane pliki rozmaitego typu (np. pdf, odt, jpg). Automatyczne wyszczególnienie wszystkich załączników pod wpisem (tak jak robi się to w mailach) jest w Django niezwykle proste i naturalne.

Model:

from django.db import models
 
class Entry(models.Model):
    title = models.CharField(max_length = 60)
    body = models.TextField()
    date = models.DateTimeField(auto_now=True)
 
class File(models.Model):
    filename = models.FileField(upload_to='content')
    date = models.DateTimeField(auto_now=True)
    description = models.CharField(max_length = 255)
    entry = models.ForeignKey(Entry, related_name='attachments')

Przyjrzyjmy się ostatniej linijce powyższego kodu. Nawet osoba nie znająca Pythona (ale mająca pojęcie o bazach danych) jest w stanie dostrzec, że definowany jest tutaj klucz obcy. Rzeczywiście, zdefiniowaliśmy relację jeden do wielu, każdy załadowany plik może być przyporządkowany do dokładnie jednego wpisu, a wpis w konsekwencji może mieć wiele załączników.

Żeby zrozumieć na czym polega w tym wypadku magia Django, należy sobie uświadomić, że w języku baz danych (SQL), żeby wyświetlić załączniki przynależne do dokumentu należałoby je "wyszukać" (np. poleceniem w rodzaju SELECT * FROM FILES WHERE entry_id=id).

W Django niczego nie trzeba wyszukiwać. Instancja klasy Entry zawiera odpowiednie informacje.
W linii poleceń znajdziemy je pisząc entry.attachments.all(), gdzie entry jest konkretnym obiektem klasy Entry. Jeśli skorzystamy z widoku generycznego do wyświetlenia treści, to wystarczy w szablonie napisać

<ul>
{% for a in object.attachments.all %}
<li><a href='/media/content/{{a.filename}}/'>{{a.description}}</a></li>
{% endfor %}
</ul>

i mamy piekną listę załączników!