Python 使用Django为多个反向外键选择相关和预取相关?
我当前在访问queryset中的值时遇到问题。我的应用程序有一个models.py,设置如下:Python 使用Django为多个反向外键选择相关和预取相关?,python,django,django-models,Python,Django,Django Models,我当前在访问queryset中的值时遇到问题。我的应用程序有一个models.py,设置如下: class Company(models.Model): name = models.Charfield(max_length=250) class Patient(models.Model): status_choices = [ ('A', 'Current Admission'), ('D', 'Discharged'),
class Company(models.Model):
name = models.Charfield(max_length=250)
class Patient(models.Model):
status_choices = [
('A', 'Current Admission'),
('D', 'Discharged'),
('U', 'Unknown'),
]
first_name = models.CharField(max_length=250)
last_name = models.CharField(max_length=250)
patient_status = models.CharField(
max_length=15,
choices=status_choices,
null=True, default='U',
verbose_name='Patient Status'
)
related_company = models.ForeignKey(Company, on_delete=models.CASCADE, related_name='patients')
class PatientStay(models.Model):
admit_date = models.DateField()
projected_dc_date = models.DateField(null=True, blank=True)
is_active = models.BooleanField(default=False)
stay_to_patient_relationship = models.ForeignKey(Patient, on_delete=models.CASCADE, related_name='stays')
class PatientLOC(models.Model):
loc_to_stay_relation = models.ForeignKey(PatientStay, on_delete=models.CASCADE, related_name='locs')
level_of_care = models.CharField(max_length=30)
loc_start = models.DateField(null=True)
loc_end = models.DateField(null=True, blank=True)
is_active = models.BooleanField(default=False)
company = Company.objects.select_related().prefetch_related('patients__stays', 'patients__stays__locs').get(id=2)
patients = company.patients.all()
for patient in patients:
...: print(patient)
...: print(patient.stays.all())
我试图做的是查询(对于特定公司)患者、他们的相关住院时间(仅针对活跃期进行筛选)以及他们的相关PatientLOC
这样的结果:
class Company(models.Model):
name = models.Charfield(max_length=250)
class Patient(models.Model):
status_choices = [
('A', 'Current Admission'),
('D', 'Discharged'),
('U', 'Unknown'),
]
first_name = models.CharField(max_length=250)
last_name = models.CharField(max_length=250)
patient_status = models.CharField(
max_length=15,
choices=status_choices,
null=True, default='U',
verbose_name='Patient Status'
)
related_company = models.ForeignKey(Company, on_delete=models.CASCADE, related_name='patients')
class PatientStay(models.Model):
admit_date = models.DateField()
projected_dc_date = models.DateField(null=True, blank=True)
is_active = models.BooleanField(default=False)
stay_to_patient_relationship = models.ForeignKey(Patient, on_delete=models.CASCADE, related_name='stays')
class PatientLOC(models.Model):
loc_to_stay_relation = models.ForeignKey(PatientStay, on_delete=models.CASCADE, related_name='locs')
level_of_care = models.CharField(max_length=30)
loc_start = models.DateField(null=True)
loc_end = models.DateField(null=True, blank=True)
is_active = models.BooleanField(default=False)
company = Company.objects.select_related().prefetch_related('patients__stays', 'patients__stays__locs').get(id=2)
patients = company.patients.all()
for patient in patients:
...: print(patient)
...: print(patient.stays.all())
- 公司:
- -病人
- --停留
- ---LOC's
- -病人
- --停留
- ---LOC's
- -病人
- --停留
- ---LOC's
class Company(models.Model):
name = models.Charfield(max_length=250)
class Patient(models.Model):
status_choices = [
('A', 'Current Admission'),
('D', 'Discharged'),
('U', 'Unknown'),
]
first_name = models.CharField(max_length=250)
last_name = models.CharField(max_length=250)
patient_status = models.CharField(
max_length=15,
choices=status_choices,
null=True, default='U',
verbose_name='Patient Status'
)
related_company = models.ForeignKey(Company, on_delete=models.CASCADE, related_name='patients')
class PatientStay(models.Model):
admit_date = models.DateField()
projected_dc_date = models.DateField(null=True, blank=True)
is_active = models.BooleanField(default=False)
stay_to_patient_relationship = models.ForeignKey(Patient, on_delete=models.CASCADE, related_name='stays')
class PatientLOC(models.Model):
loc_to_stay_relation = models.ForeignKey(PatientStay, on_delete=models.CASCADE, related_name='locs')
level_of_care = models.CharField(max_length=30)
loc_start = models.DateField(null=True)
loc_end = models.DateField(null=True, blank=True)
is_active = models.BooleanField(default=False)
company = Company.objects.select_related().prefetch_related('patients__stays', 'patients__stays__locs').get(id=2)
patients = company.patients.all()
for patient in patients:
...: print(patient)
...: print(patient.stays.all())
但这样的事情是行不通的:
company = Company.objects.select_related().prefetch_related('patients__stays', 'patients__stays__locs').get(id=2)
patients = company.patients.all()
for patient in patients:
...: print(patient)
...: for stay in patient.stays.all():
...: print(stay)
...: for loc in patient.stays.locs.all():
...: print(loc)
除了我使用一堆嵌套for循环之外,最好的方法是什么?在psuedocode中,有没有一种方法可以像这样对患者进行循环:
for patient in patients:
print(patient)
print(patient.stay)
print(patient.stay.loc)
我已经为此挣扎了一段时间,我已经猜不出来了。文档让我找到了与select_相关的和prefetch_相关的(我确信我在某种程度上使用了错误的方法)
感谢您的帮助。您可以嵌套预回迁电话:
from django.db.models import Prefetch
patients = Patient.objects.filter(company__id=2).prefetch_related(
Prefetch(
'stays',
queryset=PatientStay.objects.prefetch_related('locs')
))
for patient in patients:
print(patient)
print([stay for stay in patient.stays.all()])
print([loc for stay in patient.stays.all() for loc in stay.locs.all()])
仅供参考:
select\u related
在这里没有为您做任何事情。与预取相关的操作只会保存数据库行程。如果您不关心查询,那么嵌套for循环代码的唯一问题是patient.stays.locs.all()的行-这将是loc in staid.locs.all()的-您就快到了!这非常有用,感谢您提供嵌套的预回迁呼叫信息。如何从模板访问此文件?我不能(至少我可以看到)在模板中使用列表理解,也不会像stay-in-patient.stay.filter(is_-active=True)那样使用任何内容。我是否需要以某种方式在我的视图函数中执行这些操作,然后以这种方式保存它们>作为上下文传递?我正在为这一个而奋斗。没关系,我能够循环通过它,但我必须在没有理解的情况下使用Django过滤器,而不是queryset过滤器。