Django 快捷键嵌套外键
Django Shortcut nested foreign key
假设我的 models.py 中有以下内容:
class Book:
pass
class Part:
book = models.ForeignKey(Book)
class Chapter:
part = models.ForeignKey(Part)
number = models.IntegerField()
我愿意
book = Book.objects.get(id=someID)
chapters = Book.chapters.get(number=4)
什么是干净的方法?我想到了书上的经理class,但它似乎不适用于这种情况。
当然,我可以在 class 书中实现方法 get_chapters,但我想避免这种情况。
有什么想法吗?
对 FK 字段使用 related_name 参数,结合对查询集的 prefetch_related,将允许您以最小的性能损失获取与书籍相关的所有信息(每个 prefetch_related 参数调用单独的查询)。
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()
您也可以在模板中执行此操作。
但是,对于最高效的解决方案,还要从章节中保存 FK 到书中。这可以通过覆盖 save 方法轻松完成。
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())
假设我的 models.py 中有以下内容:
class Book:
pass
class Part:
book = models.ForeignKey(Book)
class Chapter:
part = models.ForeignKey(Part)
number = models.IntegerField()
我愿意
book = Book.objects.get(id=someID)
chapters = Book.chapters.get(number=4)
什么是干净的方法?我想到了书上的经理class,但它似乎不适用于这种情况。
当然,我可以在 class 书中实现方法 get_chapters,但我想避免这种情况。
有什么想法吗?
对 FK 字段使用 related_name 参数,结合对查询集的 prefetch_related,将允许您以最小的性能损失获取与书籍相关的所有信息(每个 prefetch_related 参数调用单独的查询)。
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()
您也可以在模板中执行此操作。
但是,对于最高效的解决方案,还要从章节中保存 FK 到书中。这可以通过覆盖 save 方法轻松完成。
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())