如何将关联Insuree与Service表的SQL查询转为等价Django Queryset?
修正SQL关联查询的Django实现
原始SQL需求
SELECT Gender, ServCode FROM [openimisproductTestDb_16_08_22].[dbo].[tblInsuree] JOIN [openimisproductTestDb_16_08_22].[dbo].[tblServices] ON [openimisproductTestDb_16_08_22].[dbo].[tblInsuree].AuditUserID = [openimisproductTestDb_16_08_22].[dbo].[tblServices].AuditUserID WHERE Gender = 'F' AND ServCode = 'F4'
原代码问题
你之前的代码错误地将Service表中code='F4'的计数与Insuree表中gender='F'的计数做按位或操作,完全没有实现两表通过AuditUserID关联、同时满足两个筛选条件的核心逻辑。
修正后的Django实现
假设你的Django模型字段对应SQL表结构如下:
from django.db import models class Insuree(models.Model): gender = models.CharField(max_length=1) audit_user_id = models.IntegerField(db_column='AuditUserID') validity_from = models.DateField() validity_to = models.DateField(null=True) # 其他业务字段... class Service(models.Model): serv_code = models.CharField(max_length=10, db_column='ServCode') audit_user_id = models.IntegerField(db_column='AuditUserID') # 其他业务字段...
以下是修正后的函数,完整实现关联筛选+计数的需求(如需获取具体记录,可调整返回逻辑):
from django.db.models import OuterRef import datetime def assisted_birth_with_cs_query(user, **kwargs): date_from = kwargs.get("date_from") date_to = kwargs.get("date_to") hflocation = kwargs.get("hflocation") format = "%Y-%m-%d" date_from_object = datetime.datetime.strptime(date_from, format) date_from_str = date_from_object.strftime("%d/%m/%Y") date_to_object = datetime.datetime.strptime(date_to, format) date_to_str = date_to_object.strftime("%d/%m/%Y") dictBase = { "dateFrom": date_from_str, "dateTo": date_to_str, } if hflocation and hflocation != "0": hflocationObj = HealthFacility.objects.filter( code=hflocation, validity_to__isnull=True ).first() dictBase["fosa"] = hflocationObj.name dictGeo = {'health_facility': hflocationObj.id} # 核心关联筛选逻辑:匹配AuditUserID一致、同时满足两个条件的记录 filtered_insurees = Insuree.objects.filter( validity_from__gte=date_from, validity_to__lte=date_to, gender='F', **dictGeo, # 确保当前Insuree的AuditUserID存在于ServCode='F4'的Service记录中 audit_user_id__in=Service.objects.filter(serv_code='F4').values('audit_user_id') ) # 统计符合条件的记录数 count = filtered_insurees.count() # 如需获取SQL中SELECT的Gender和ServCode字段值,启用以下代码 # results = filtered_insurees.values('gender').annotate( # serv_code=Service.objects.filter( # audit_user_id=OuterRef('audit_user_id'), # serv_code='F4' # ).values('serv_code')[:1] # ) dictBase["post"] = str(count) return dictBase
关键说明
- 使用
audit_user_id__in子查询实现SQL中的JOIN逻辑,确保Insuree的AuditUserID与Service表中ServCode='F4'的记录匹配。 - 保留了原函数中日期范围、健康设施的筛选逻辑,适配原有业务需求。
- 若需要获取具体字段值,可启用注释中的
results代码块,通过子查询关联拉取对应的ServCode。
内容的提问来源于stack exchange,提问作者user20522053
相关产品推荐
相关产品推荐

