Pau*_*lin 32 django django-models django-queryset django-managers django-1.5
我在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)
Run Code Online (Sandbox Code Playgroud)
当我有人员记录并且我想找到该人的经理时,我必须这样做
manager = person.position.report_to.person_set.all()[0]
# Can't use .first() because we haven't upgraded to 1.6 yet
Run Code Online (Sandbox Code Playgroud)
如果我找到一个人QuerySet,我可以加入(并避免第二次访问数据库)使用position和report_to using Person.objects.select_related('position', 'position__reports_to').filter(...),但有没有办法避免再次访问数据库以获取person_set?我尝试添加'position__reports_to__person_set'或刚刚position__reports_to__person到select_related,但是这似乎并没有更改查询.这prefetch_related是为了什么?
我想创建一个自定义管理器,这样当我进行查询以获取Person记录时,我也会获得他们的PositionHeirarchy和他们的经理的Person记录,而不会再往返数据库.这是我到目前为止:
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(
)
Run Code Online (Sandbox Code Playgroud)
Kev*_*nry 31
是的,这prefetch_related()就是为了什么.它需要一个额外的查询,但想法是它将立即获得所有相关信息,而不是每次Person.
在你的情况下:
qs.select_related('position__report_to')
.prefetch_related('position__report_to__person_set')
Run Code Online (Sandbox Code Playgroud)
无论Persons原始查询集中的数量是多少,都应该需要两个查询.
比较文档中的这个例子:
>>> Restaurant.objects.select_related('best_pizza')
.prefetch_related('best_pizza__toppings')
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
21758 次 |
| 最近记录: |