2012-06-01 2 views
1
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, связанный с некоторыми B-экземплярами по его параметрам. я пытаюсь сделать:select_related() с фильтром() + Q()

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?

Thanx!

[PS] Теперь это работает, но не совсем так, как надо:

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

ответ

0

фильтр на B вместо, а затем от B получить инстанс

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 со всеми запросами вместо того, чтобы сделать вызов для восстановления b_with_a для каждого шага в цикле. Измените это, если оно не соответствует вашей цели.

+0

Спасибо, Микаэль. В это время я сделал это, но мне это не совсем удобно, потому что я получил точное соответствие с оригинальным экземпляром экземпляров B-экземпляров. В этом варианте осуществления будут получены любые B-экземпляры, совпадающие с одним из экземпляров dict-instance –

-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) 
Смежные вопросы