【问题标题】:Django: getting the list of related records for a list of objectsDjango:获取对象列表的相关记录列表
【发布时间】:2011-02-01 17:25:06
【问题描述】:

我有两个一对多相关的模型:

class Person(models.Model):
    name      = models.CharField(max_length=255);
    surname   = models.CharField(max_length=255);     
    age       = models.IntegerField(); 


class Dog(models.Model):
    name      = models.CharField(max_length=255);
    owner     = models.ForeignKey('Person');

我想输出一个人员列表,并在每个人下方输出他拥有的狗的列表。我可以这样做:

在视图中:

persons = Person.objects.all()[0:100];

在模板中:

{% for p in persons %}
    {{ p.name }} has dogs:<br />
    {% for d in persons.dog_set.all %}
        - {{ d.name }}<br />
    {% endfor %}
{% endfor %}

但是如果我那样做,Django 会执行 101 个 SQL 查询,效率很低。

我尝试制作一个自定义管理器,它将获取所有的人,然后是所有的狗并在 python 中链接它们,但是我不能使用分页器(我的另一个问题:Django: Paginator + raw SQL query)而且它看起来很丑.

有没有更优雅的方式来做到这一点?

更新

基于@Daniel Roseman 的博客条目的解决方案

all_objects = Person.objects.select_related().all();

paginator = Paginator(all_objects, 100);

try:
    page = int(request.GET.get('page', '1'))
except ValueError:
    page = 1

try:
    current_page = paginator.page(page)
except (EmptyPage, InvalidPage):
    current_page = paginator.page(paginator.num_pages)

person_list = dict([(obj.id, obj) for obj in current_page.object_list])
id_list = [obj.id for obj in current_page.object_list]

objects = Dog.objects.filter(owner__id__in=id_list)

relation_dict = {}
for obj in objects:
    relation_dict.setdefault(obj.owner_id, []).append(obj)

for id, related_items in relation_dict.items():
    person_list[id].dogs = related_items

【问题讨论】:

  • 请参阅my blog(对插件感到抱歉),我在其中描述了一种有效的方法。

标签: django foreign-keys


【解决方案1】:

使用较新版本的 Django(>=1.7 或什至可能是一些较旧的版本),您只需替换您的

persons = Person.objects.all()[0:100]

与

persons = Person.objects.prefetch_related('dog_set').all()[0:100]

就是这样,如果您使用的是 Django>=1.7,则无需继续使用旧的解决方法

prefetch_related 上的官方文档在这里: https://docs.djangoproject.com/en/2.0/ref/models/querysets/#prefetch-related

【讨论】:

    猜你喜欢
    • 2018-03-31
    • 1970-01-01
    • 2015-04-27
    • 1970-01-01
    • 2015-03-24
    • 1970-01-01
    • 2013-02-16
    • 2017-11-05
    • 1970-01-01
    相关资源
    最近更新 更多