【问题标题】:How to filter foreign key objects in django queries?如何在 django 查询中过滤外键对象?
【发布时间】:2019-04-12 07:57:57
【问题描述】:

我有两个模型,一个通过foreign key 与另一个相关,就像这样

class CapturedPrescriptionModel(ColModel):
    p_id = models.IntegerField()
    p_age = models.IntegerField()
    p_gender = models.CharField(max_length=10)
    p_care_type = models.CharField(max_length=100)
    bacteria_id = models.ForeignKey(BacteriaListModel, 
              on_delete=models.CASCADE, null=True)

class SuggestedAntibioticsModel(ColModel):
    prescription_id = models.ForeignKey(CapturedPrescriptionModel, 
                  related_name='antibiotics', 
                   on_delete=models.CASCADE)
    cat_ids = models.TextField()
    flag = models.IntegerField(default=0)

现在我想要所有prescriptionssuggested antibiotics 其中flag=1

我已尝试使用 CapturedPrescriptionModel.objects.filter(antibiotics__flag=1),但它过滤的是处方而不是查询集中的抗生素列表。

 [
    {
    "id": 7,
    "p_id": 0,
    "p_age": 19,
    "p_gender": "Male",
    "p_care_type": "ICU",
    "bacteria_id": null,
    "antibiotics": [
        {
            "id": 188,
            "cat_ids": "[]",
            "flag": 0,
            "antibiotic_id_id": 87,
            "prescription_id_id": 7
        },
        {
            "id": 187,
            "cat_ids": "[]",
            "flag": 1,
            "antibiotic_id_id": 112,
            "prescription_id_id": 7
        },
      ......
      ]
}
....
]

我的预期结果会是这样的

    [
        {
        "id": 7,
        "p_id": 0,
        "p_age": 19,
        "p_gender": "Male",
        "p_care_type": "ICU",
        "bacteria_id": null,
        "antibiotics": [
            {
                "id": 187,
                "cat_ids": "[]",
                "flag": 1,
                "antibiotic_id_id": 112,
                "prescription_id_id": 7
            }
          ]
}
....
]

【问题讨论】:

  • 您想要所有处方(即使没有antibiotics__flag=1 的处方),但antibiotics 集应该只包含带有flag=1 的处方?
  • 是的,对于那些任何antibiotics__flag=1 都不够用的处方应该是一个空列表

标签: django django-models one-to-many django-orm


【解决方案1】:

如果您只想过滤相关对象,而不是主要对象,则需要过滤 Prefetch

from django.db.models import Prefetch

CapturedPrescriptionModel.objects.prefetch_related(Prefetch(
    'antibiotics',
    queryset=SuggestedAntibioticsModel.objects.filter(flag=1)
)

然后,您必须确保单个处方对象上的 antibiotics 只能通过 prescription.antibiotics.all() 访问,否则不使用预取,您将再次获得所有抗生素。

【讨论】:

    【解决方案2】:

    收集所有处方:

    prescriptions = CapturedPrescriptionModel.objects.all()
    
    for prescription in prescriptions:
        prescription.antibiotics = prescription.antibiotics.filter(flag=1)
    
    # at this time presciptions should be prepared, just make sure to not save them...
    

    您还可以扩展您的模型以具有该列表的属性。

    class CapturedPrescriptionModel(ColModel):
        p_id = models.IntegerField()
        p_age = models.IntegerField()
        p_gender = models.CharField(max_length=10)
        p_care_type = models.CharField(max_length=100)
        bacteria_id = models.ForeignKey(BacteriaListModel, 
                  on_delete=models.CASCADE, null=True)
    
        @property
        def flagged_antibiotics(self):
            try:
                return self.antibiotics.filter(flag=1)
            except Exception:
                return []
    
    class SuggestedAntibioticsModel(ColModel):
        prescription_id = models.ForeignKey(CapturedPrescriptionModel, 
                      related_name='antibiotics', 
                       on_delete=models.CASCADE)
        cat_ids = models.TextField()
        flag = models.IntegerField(default=0)
    

    这样的事情是我第一次尝试

    【讨论】:

      猜你喜欢
      • 2014-01-08
      • 2014-08-06
      • 1970-01-01
      • 2013-09-17
      • 2021-09-21
      • 1970-01-01
      • 2018-03-04
      • 2023-03-11
      • 2021-11-17
      相关资源
      最近更新 更多