Python 带内部查询的Django过滤器?

Python 带内部查询的Django过滤器?,python,django,django-models,django-queryset,Python,Django,Django Models,Django Queryset,基于以下模型: class OpportunityDetail(models.Model): ContactDetail = models.ForeignKey(ContactDetail, on_delete=models.CASCADE, related_name='OpportunityContactDetails') Stage = models.CharField(max_length=20, unique = False, choices=stages) class

基于以下模型:

class OpportunityDetail(models.Model):
    ContactDetail = models.ForeignKey(ContactDetail, on_delete=models.CASCADE, related_name='OpportunityContactDetails')
    Stage = models.CharField(max_length=20, unique = False, choices=stages)

class ProductDetail(models.Model):
    Name = models.CharField(max_length=30, unique = False)
    Amount = models.DecimalField(max_digits=12, decimal_places=2, unique = False)

class ProductItemDetail(models.Model):
    ProductDetail = models.ForeignKey(ProductDetail, on_delete=models.CASCADE, related_name='ProductDetails')
    OpportunityDetail = models.ForeignKey(OpportunityDetail, on_delete=models.CASCADE, related_name='OpportunityDetails')
    ChildrenDetail = models.ForeignKey(ChildrenDetail, on_delete=models.CASCADE, related_name='ChildrenProduct')
当我询问机会时,我通常会这样做:

oppLST = OpportunityDetail.objects.filter(ContactDetail = myCon.id)
但是,我想知道如何获得产品项的内部查询?在sql中,我将执行以下操作:

SELECT Id, Stage, (SELECT Id, ProductDetail, ProductDetail.Name FROM ProductItemDetail) FROM OpportunityDetail WHERE ContactDetail = myCon.id

我想知道是否有可能在django做类似的事情。根据您想要的结果,有几种方法可以解决这个问题。这里有一种方法可能对你来说就足够了。这不使用django子查询,只通过遍历模型中的外键关系来收集所需的详细信息:

oppLST=OpportunityDetail.objects.filter(ContactDetail=myCon.id).值(
"id","stage",,
“OpportunityDetails\uuuu id”,
“OpportunityDetails\uuuuu ProductDetail\uuuuuuuu id”,
'机会详细信息\产品详细信息\名称'
)
上述内容将为您提供词典列表,例如:

[
  {'id': 1, 'stage': 'Stage 1', 'OpportunityDetails__id': 1, 'OpportunityDetails__ProductDetail__id': 1, 'OpportunityDetails__ProductDetail__Name': 'details'},
  {'id': 1, 'stage': 'Stage 1', 'OpportunityDetails__id': 1, 'OpportunityDetails__ProductDetail__id': 2, 'OpportunityDetails__ProductDetail__Name': 'details more'},
  {'id': 1, 'stage': 'Stage 1', 'OpportunityDetails__id': 1, 'OpportunityDetails__ProductDetail__id': 3, 'OpportunityDetails__ProductDetail__Name': 'details three'},
  {'id': 2, 'stage': 'Stage B', 'OpportunityDetails__id': 2, 'OpportunityDetails__ProductDetail__id': 5, 'OpportunityDetails__ProductDetail__Name': 'interesting details'},
 ...
]
你可以拿着这个,然后从中得到你需要的东西

请注意,您在模型定义中使用“related_name”的方式有点不清楚,并且隐藏了该属性的实际含义和用法。此属性通过外键提供反向访问,并且应以指示的方式命名。此外,为了避免混淆和可能出现的错误,模型中的字段名称应为小写,以免与实际的模型名称混淆(例如,
ProductDetail
是ProductItemDetail字段还是模型ProductItemDetail模型?)

这里有一个建议:

class OpportunityDetail(models.Model):
contact\u detail=models.ForeignKey(ContactDetail,on\u delete=models.CASCADE,related\u name='opportunities')
stage=models.CharField(最大长度=20,唯一性=False,选项=stages)
类别ProductDetail(models.Model):
name=models.CharField(最大长度=30,唯一性=False)
金额=型号。小数字段(最大位数=12,小数位数=2,唯一位数=False)
类ProductItemDetail(models.Model):
product\u detail=models.ForeignKey(ProductDetail,on\u delete=models.CASCADE,相关的\u name='product\u项目')
opportunity\u detail=models.ForeignKey(opportunity detail,on\u delete=models.CASCADE,相关的\u name='product\u项)
ChildrenDetail=models.ForeignKey(ChildrenDetail,on\u delete=models.CASCADE,related\u name='product\u items')
通过上述更正,django queryset变为:

oppLST = OpportunityDetail.objects.filter(contact_detail=myCon.id).values(
   'id', 'stage', 
   'product_items__id', 
   'product_items__product_detail__id', 
   'product_items__product_detail__name'
)
希望这有帮助,让我知道如果有什么需要澄清

另外:您在上面的评论中提到,您希望在模板中使用此选项。您可以直接在模板中引用相关名称,如下所示:

opportunities=OpportunityDetail.objects.filter(ContactDetail=myCon.id)
模板:

{%用于opportunity%中的opportunity}
...
{opportunity.product_items%}
{{product_item.product_detail.id}

{{product_item.product_detail.name}

{%endfor%} {%endfor%}

这可能是你需要的最简单的东西。在模板中执行此操作而不是在数据到达模板之前使用单个查询执行此操作的性能稍差,但与小数据集无关。

是的,可以使用django在查询中执行子查询。为了澄清,您希望SQL查询的结果在您给出的示例中是什么?@PeterGalfi在我的模板中,我想循环浏览opportunities,对于eahc one,我想循环浏览项目,这样我可以显示一个opp列表,对于每个opp,一个他们的项目列表,是否可以使用查询“django语言”?我的意思是以OpportunityDetail.objects.filter的格式。。。。