Reputation: 140
I have two models, one related to other by foreign key
like this
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)
Now I want all the prescriptions
with suggested antibiotics
where flag=1
I have tried with CapturedPrescriptionModel.objects.filter(antibiotics__flag=1)
but that filter the prescriptions not the list of antibiotics in the queryset.
[
{
"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
},
......
]
}
....
]
My expected result will be like this
[
{
"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
}
]
}
....
]
Upvotes: 0
Views: 149
Reputation: 5730
You need a filtered Prefetch
if you want to filter the related objects only, not the main objects:
from django.db.models import Prefetch
CapturedPrescriptionModel.objects.prefetch_related(Prefetch(
'antibiotics',
queryset=SuggestedAntibioticsModel.objects.filter(flag=1)
)
You then have to make sure that antibiotics
on the individual prescription objects is only accessed with prescription.antibiotics.all()
, otherwise the prefetch is not used and you'll get all antibiotics again.
Upvotes: 2
Reputation: 424
Collect all Prescriptions:
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...
You could also extend your model to have a property for that list.
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)
Something like this would be my first take on that
Upvotes: 0