python - 将具有多个循环和逻辑的代码简化为查询集聚合
问题描述
我的模型:
class customer(models.Model):
cstid = models.AutoField(primary_key=True, unique=True)
insurance_number = models.CharField(max_length=100, blank=True, null=True)
name = models.CharField(max_length=35)
ageyrs = models.IntegerField(blank=True)
class Admission(models.Model):
id = models.AutoField(primary_key=True, unique=True)
clinic = models.ForeignKey(Clinic, on_delete=models.CASCADE)
customer = models.ForeignKey(customer, on_delete=models.CASCADE)
diagnosis = models.CharField(max_length=2000, default='', blank=True)
date_admission = models.DateTimeField(default=timezone.now)
ward = models.ForeignKey(Ward, on_delete=models.CASCADE)
bed = models.ForeignKey(Bed, on_delete=models.CASCADE)
discharged = models.BooleanField(default=False)
ip_number = models.IntegerField(blank=True)
ip_prefix = models.CharField(max_length=20, default='', blank=True)
我的目标:为查询过滤器设置一个变量,向查询集添加一个属性“is_admitted”,以便我可以将此查询集传递给模板并在显示数据时使用该属性。
代码:
def is_admitted(cust):
admission = Admission.objects.filter(customer=cust, discharged=False)
admission_results = len(admission)
if admission_results > 0:
return True
return False
my_q = or_q_if_truthfull(
cstid=HospitalID,
name__lower__contains=name.lower() if name else None,
ageyrs=ageyrs if ageyrs.isdigit() else None,
agemnths=agemnths if agemnths.isdigit() else None,
mobile__contains=mobile if mobile else None,
alternate__contains=alternate if alternate else None,
email__lower__contains=email.lower() if email else None,
address__lower__contains=address.lower() if address else None,
city__lower__contains=city.lower() if city else None
)
ORSearchResult = customer.objects.filter(my_q, linkedclinic=clinicobj)
cust_set = []
cust_admission_status = []
for cust in ORSearchResult:
cust_set.append(cust)
cust_admission_status.append(is_admitted(cust))
print(f"Customer name: {cust.name} Admission status: {is_admitted(cust)}")
cust_templ_set = zip(cust_set, cust_admission_status)
在模板中,我会这样做:
{% for cust, status in cust_templ_set %}
{{ cust.name }} {{ status }}
{% endfor %}
我想了解如何通过在查询集上生成聚合来转换上面的代码,以便我可以使用查询的属性,并将模板代码更改为以下,并避免视图中的循环和 zip . 这样模板代码就变成了:
{% for cust in customers %}
{{ cust.name }} {{ cust.is_admitted }}
{% endfor %}
我不确定我是否完全有道理,并且可以进一步解释。
解决方案
我不确定我是否理解正确,也许你可能想要这个:
cust = customer.objects.filter(my_q, linkedclinic=clinicobj)
is_admitted_sub_q = Admission.objects.filter(customer=OuterRef('pk'), discharged=False)
cust_templ_set = cust.annotate(is_admitted=Exists(is_admitted_sub_q), )
这将返回带有附加字段的客户列表,如果在 中至少存在一个链接(到此客户)记录,则该字段is_admitted
将显示。True
Admission
推荐阅读
- android - 如何创建自定义字符串并动态填充它?
- amazon-ec2 - 在多个 EC2 实例上运行的同一个 Kinesis Consumer
- java - JTree 未显示在 SplitPane 的左侧 ScrollPane 内
- c - 在接受 1 个输入后将结构写入文件,导致分段错误
- javascript - 相当于Firestore中的.push?
- c++ - 函数重载:内置与用户定义类型
- java - 如何使用 REST API 发布 Yammer 的投票?
- javascript - React 代理在 url 中创建双“帖子”
- python - 使用beautifulsoup和python从json中提取数据
- javascript - 除了其他,希利奥斯倒数计时器