我在Django 有两个模特.第一个层次是什么工作职能(职位)向哪些其他职位汇报,第二个层次是人员及其担任的工作职能.

class PositionHierarchy(model.Model):
    pcn = models.CharField(max_length=50)
    title = models.CharField(max_length=100)
    level = models.CharField(max_length=25)
    report_to = models.ForeignKey('PositionHierachy', null=True)


class Person(model.Model):
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    ...
    position = models.ForeignKey(PositionHierarchy)

当我有个人记录,并且我想找到该人的经理时,我必须这样做

manager = person.position.report_to.person_set.all()[0]
# Can't use .first() because we haven't upgraded to 1.6 yet

如果我得到的是QuerySet分的人,我可以加入position并向using Person.objects.select_related('position', 'position__reports_to').filter(...)报告(并避免第二次访问数据库),但是有没有办法避免再次访问数据库以获得person设置?我试着在select_related中添加'position__reports_to__person_set'position__reports_to__person,但这似乎并没有改变查询.这就是prefetch_related的用途吗?

我想创建一个自定义管理器,这样当我进行查询以获取人员记录时,我还可以获得他们的PositionHeirarchy和他们经理的人员记录,而不需要往返于数据库.这就是我到目前为止所掌握的情况:

class PersonWithManagerManager(models.Manager):
    def get_query_set(self):
        qs = super(PersonWithManagerManager, self).get_query_set()
        return qs.select_related(
            'position',
            'position__reports_to',
        ).prefetch_related(
        )

推荐答案

是的,这就是prefetch_related()美元的用处.它将需要额外的查询,但是其 idea 是它将一次获得所有相关信息,而不是每Person一次.

就你而言:

qs.select_related('position__report_to')
  .prefetch_related('position__report_to__person_set')

应该需要两个查询,而不管原始查询集中有多少个Persons.

比较documentation个示例中的以下示例:

>>> Restaurant.objects.select_related('best_pizza')
                      .prefetch_related('best_pizza__toppings')

Django相关问答推荐

Htmx如何从事件中访问数据?

DRF中没有参数的视图的警告-壮观

带有变量键的 Django 模板括号表示法不起作用

从多个数据库访问 Django 会话

使用自定义的AuthBackend时,无法使用request.user.is_authenticated或@login_required修饰符

如何将数据(具体归档)从views.py 传递到models.py

在 Django Admin change_list 视图中更改 list_editable 字段时保存 Django 模型

如何获得用户权限?

Django 密码以什么格式存储在数据库中?

Django Facebook Connect 应用推荐

获取 Django 中的缓存键列表

Django rest-auth allauth 注册,带有邮箱、名字和姓氏,没有用户名

导入错误无法在windows环境下导入名称execute_manager

如何将 django csrf 令牌直接嵌入 HTML?

Django 模型:delete() 未触发

Django 应用程序运行良好,但收到 TEMPLATE_* 警告消息

如何过滤(或替换)在 UTF-8 中占用超过 3 个字节的 unicode 字符?

过滤查询参数

Django - TypeError - save() 得到了一个意外的关键字参数force_insert

Django 字符串到日期格式