问题描述
我正在使用DRF API,但对django属性并不完全熟悉。
数据库关系是经典的。公司有应聘者可以申请的不同职位。每个作业都有多个匹配项,匹配项是作业和候选者之间的联接表。比赛的状态不同,代表申请过程的不同阶段。
这是交易: 我正在使用drf视图集从api获取数据。该视图集使用序列化器来获取特定字段,特别是作业每个状态的匹配数。序列化程序的简化版本看起来像这样。
class Team2AmBackofficeSerializer(normal2JobSerializer):
class Meta:
model = Job
fields = (
'pk','name','company','company_name','job__nb_matches_proposition','job__nb_matches_preselection','job__nb_matches_valides','job__nb_matches_pitches','job__nb_matches_entretiens','job__nb_matches_offre',)
job__xxx
字段正在使用装饰器@property
,例如:
@property
def job__nb_matches_offre(self):
return self.matches.filter(current_status__step_name='Offre').count()
问题是,每当我将这些属性之一添加到序列化器的字段中时,数据库查询的数量就会大大增加。这当然是由于每个属性都多次调用DB。所以这是我的问题:
是否可以通过更改序列化程序中的某些内容或以其他方式获取特定状态的匹配数来优化对数据库的查询数量? >
我看过select_related
和prefetch_related
。这样我就可以减少获取有关公司的信息时的查询数量,但实际上却不能真正找到匹配的数量。
非常感谢您的帮助:)
解决方法
您想要的是使用这些值annotate https://docs.djangoproject.com/en/3.0/topics/db/aggregation/,这将导致数据库仅在一个查询中进行所有计数。结果比您当前的解决方案快得多。
示例:
from django.db.models import Count,Q
Job.objects.annotate(
'nb_matches_offre'=Count(
'pk',filter=Q(current_status__step_name='Offre')
),'nb_matches_entretiens'=Count(...)
).all()
结果查询集将包含具有计数的属性job_obj.nb_matches_offre
和job_obj.nb_matches_entretiens
的Job对象。
另请参阅{{3}}