Mithilfe von related_name-Argumenten für FK-Felder, gekoppelt mit prefetch_related für ein Abfrage-Set, können Sie alle Informationen zu einem Buch mit minimalem Performance-Treffer abrufen (jeder prefetch_related-Parameter ruft eine separate Abfrage auf).
class Book:
pass
class Part:
book = models.ForeignKey(Book, related_name="parts")
class Chapter:
part = models.ForeignKey(Part, related_name="chapters")
number = models.IntegerField()
# fetch a book and all related info w/ only 2 db hits
book = Book.objects.first().prefetch_related("parts","parts__chapters")
print(book.parts.all()) # returns all parts for book
for part in book.parts.all():
print part.chapters.all()
Sie können dies auch in einer Vorlage tun.
Für die leistungsfähigste Lösung speichern Sie jedoch auch einen FK, um aus dem Kapitel zu buchen. Dies kann leicht durch Überschreiben der Speichermethode erfolgen.
class Chapter:
part = models.ForeignKey(Part, related_name="part_chapters")
number = models.IntegerField()
book = models.ForeignKey(Book, related_name="chapters", null=True, blank=True) # allow null/blank values; will be populated in save method
def save(self, *args, **kwargs):
self.book = self.part.book
super(Chapter, self).save(*args, **kwargs)
>>> book = Book.objects.first().prefetch_related("parts","chapters")
>>> print(book.parts.all()) # returns all parts for book
>>> print(book.chapters.all())
https://docs.djangoproject.com/de/1.9/topics/db/queries/#backwards-related-objects – eustass