select_related()with filter()+ Q()

时间:2012-06-01 10:30:33

标签: django django-select-related django-q

class A(models.Model):
    pass

class B(models.Model):
    a = models.ForeignKey(A)
    content_type = models.ForeignKey(ContentType)
    object_id = models.IntegerField()
    content_object = generic.GenericForeignKey('content_type', 'object_id')

如何获取A-instance,它通过参数与某些B-instance链接。 我试着这样做:

instances = { '1':10, '2':20, '3':30 }
for ct, id in instances.items():
qset |= Q(content_type=int(ct), object_id=int(id))
a = A.objects.all().select_related().filter(qset)

错误无效:«无法将关键字'object_id'解析为字段。» 我可以通过链接B获得什么?

感谢名单!

[PS] 现在这个工作,但不是应该的:

a_all = A.objects.all()
for a in a_all:
    print a.a_set.filter(qset)

2 个答案:

答案 0 :(得分:0)

在B上过滤,然后从B过滤获取A实例

instances = { '1':10, '2':20, '3':30 }

for ct, id in instances.items():
    qset = qset | Q(content_type=int(ct), id=int(id))

b_with_a = B.objects.select_related().filter(qset)

for each b in b_with_a:
    print b.A.what_ever_field

请注意,我使用所有查询构建一个qset,而不是为循环中的每个步骤调用retreive b_with_a。如果它不符合您的目的,请更改。

答案 1 :(得分:-1)

您可以使用lookups which span relationships

import operator
instances = { '1':10, '2':20, '3':30 }
# note the 'b__'
qset = reduce(operator.or_, (Q(b__content_type=int(x), b__object_id=y)
                             for x,y in instances.iteritems()))
qs = A.objects.filter(qset)