Django Shortcut 嵌套外键

2023-08-30Python开发问题
2

本文介绍了Django Shortcut 嵌套外键的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

假设我的 models.py 中有以下内容:

Suppose I have the following in my 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)

这样做的干净方法是什么?我想到了图书课上的经理,但它似乎不适用于这种情况.

What is a clean way to do so? I thought of a Manager on the book class but it doest not seem to work for this case.

当然,我可以在课本上实现 get_chapters 方法,但我想避免这种情况.

Of course I could implement a method get_chapters on class book but i would like to avoid this.

有什么想法吗?

推荐答案

对 FK 字段使用相关名称参数,再加上查询集的 prefetch_related,将允许您以最小的性能损失获取与书籍相关的所有信息(每个 prefetch_related 参数调用一个单独的查询).

Using related_name arguments for FK fields, coupled with prefetch_related for a queryset, will allow you to fetch all info related to a book with minimal performance hit (each prefetch_related param calls a separate query).

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

您也可以在模板中执行此操作.

You can do this in a template as well.

但是,对于最高效的解决方案,还要保存一个 FK 以从章节中预订.这可以通过重写 save 方法轻松完成.

However, for the most performant solution, save a FK to book from chapter as well. This can be easily done by overriding the save method.

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

这篇关于Django Shortcut 嵌套外键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

The End

相关推荐

在xarray中按单个维度的多个坐标分组
groupby multiple coords along a single dimension in xarray(在xarray中按单个维度的多个坐标分组)...
2024-08-22 Python开发问题
15

Pandas中的GROUP BY AND SUM不丢失列
Group by and Sum in Pandas without losing columns(Pandas中的GROUP BY AND SUM不丢失列)...
2024-08-22 Python开发问题
17

GROUP BY+新列+基于条件的前一行抓取值
Group by + New Column + Grab value former row based on conditionals(GROUP BY+新列+基于条件的前一行抓取值)...
2024-08-22 Python开发问题
18

PANDA中的Groupby算法和插值算法
Groupby and interpolate in Pandas(PANDA中的Groupby算法和插值算法)...
2024-08-22 Python开发问题
11

PANAS-基于列对行进行分组,并将NaN替换为非空值
Pandas - Group Rows based on a column and replace NaN with non-null values(PANAS-基于列对行进行分组,并将NaN替换为非空值)...
2024-08-22 Python开发问题
10

按10分钟间隔对 pandas 数据帧进行分组
Grouping pandas DataFrame by 10 minute intervals(按10分钟间隔对 pandas 数据帧进行分组)...
2024-08-22 Python开发问题
11