【问题标题】:select_related() with filter() + Q()select_related() 与 filter() + Q()
【发布时间】:2012-06-06 14:23:50
【问题描述】:
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)

没有错误:«Cannot resolve keyword 'object_id' into field.» 我可以通过链接 B 得到什么?

谢谢!

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

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

【问题讨论】:

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


    【解决方案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)
    

    【讨论】:

      【解决方案2】:

      改为过滤 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,而不是为循环中的每个步骤调用检索 b_with_a。如果它不符合您的目的,请更改它。

      【讨论】:

      • 谢谢你,米凯尔。这次我这样做了,但我不太舒服,因为我收到了与原始 B-instances 实例字典完全匹配的内容。在本实施例中,将被任何 B-instances 接收,与其中一个 dict-instance 相吻合
      猜你喜欢
      • 2011-05-08
      • 2016-10-26
      • 2014-06-01
      • 2011-12-27
      • 1970-01-01
      • 2011-10-17
      • 2013-05-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多