【发布时间】:2009-05-12 14:50:25
【问题描述】:
假设我有 2 个模型:
class Poll(models.Model):
category = models.CharField(u"Category", max_length = 64)
[...]
class Choice(models.Model):
poll = models.ForeignKey(Poll)
[...]
给定一个 Poll 对象,我可以查询它的选择:
poll.choice_set.all()
但是,是否有一个实用函数可以从一组 Poll 中查询所有选项?
实际上,我正在寻找类似以下的东西(不支持,我也不寻求它是如何实现的):
polls = Poll.objects.filter(category = 'foo').select_related('choice_set')
for poll in polls:
print poll.choice_set.all() # this shouldn't perform a SQL query at each iteration
我制作了一个(丑陋的)函数来帮助我实现这一目标:
def qbind(objects, target_name, model, field_name):
objects = list(objects)
objects_dict = dict([(object.id, object) for object in objects])
for foreign in model.objects.filter(**{field_name + '__in': objects_dict.keys()}):
id = getattr(foreign, field_name + '_id')
if id in objects_dict:
object = objects_dict[id]
if hasattr(object, target_name):
getattr(object, target_name).append(foreign)
else:
setattr(object, target_name, [foreign])
return objects
具体用法如下:
polls = Poll.objects.filter(category = 'foo')
polls = qbind(polls, 'choices', Choice, 'poll')
# Now, each object in polls have a 'choices' member with the list of choices.
# This was achieved with 2 SQL queries only.
Django 是否已经提供了一些更简单的东西?或者至少,一个 sn-p 以更好的方式做同样的事情。
你通常如何处理这个问题?
【问题讨论】:
-
也许你的 qbind 函数是可以做到的最好的。但将其打包在自定义管理器中可能是有意义的 - docs.djangoproject.com/en/dev/topics/db/managers/#id2