Python 在序列化器字段中使用属性时,如何优化DRF编号查询?

Python 在序列化器字段中使用属性时,如何优化DRF编号查询?,python,django,django-rest-framework,properties,django-serializer,Python,Django,Django Rest Framework,Properties,Django Serializer,我正在开发一个DRFAPI,我对django属性并不完全熟悉 DB关系是经典的。公司有不同的职位,求职者可以申请。每个作业都有几个匹配项,匹配项是作业和候选项之间的联接表。匹配项具有不同的状态,表示应用程序流程的不同阶段 这就是交易: 我使用drf视图集从api获取数据。此视图集使用序列化程序获取特定字段,特别是作业的每个状态的匹配数。序列化程序的简化版本如下所示 class Team2AmBackofficeSerializer(Normal2JobSerializer): clas

我正在开发一个DRFAPI,我对django属性并不完全熟悉

DB关系是经典的。公司有不同的职位,求职者可以申请。每个作业都有几个匹配项,匹配项是作业和候选项之间的联接表。匹配项具有不同的状态,表示应用程序流程的不同阶段

这就是交易: 我使用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\uuuxxx
字段使用decorator
@属性,例如:

@property
def job__nb_matches_offre(self):
    return self.matches.filter(current_status__step_name='Offre').count()
问题是每次我将这些属性中的一个添加到序列化程序的字段中时,DB查询的数量都会显著增加。这当然是因为每个属性都多次调用DB。所以我的问题是:

有没有办法通过更改序列化程序中的内容或以不同方式获取特定状态的匹配数来优化对数据库的查询数?

我已经看过了
选择与之相关的
预取与之相关的
。这允许我在获取有关公司的信息时减少查询的数量,但实际上并没有减少匹配的数量

非常感谢您的帮助:)

您需要的是使用这些值设置查询,这将导致数据库在一次查询中完成所有计数。结果比您当前的解决方案快得多

例如:

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_entriens


另请参见

您可以使用annotate(例如)执行一些技巧来预取这些信息,但是,您的查询仍然非常庞大。在模型中随意创建这些字段,并在创建/编辑/删除时对其进行更新(如果不需要即时准确性,则在异步任务中更新)是否可以接受?这肯定会更有效。非常感谢!这就是我需要的。我只需要做一个小的语法修改就可以了。下面是它最后的样子:
nb\u matches\u offre=Sum(Case(当(匹配当前状态步骤),然后=1),default=0,output\u field=IntegerField())
@AntoineQuellier好听。我没有测试我的代码片段,我只是查看了代码中的内容,并对其进行了简化和修改。它实际上可能需要一个子查询来进行计数。但你的解决方案听起来也不错。如果您关心数据库中的性能,那么可以从postgres日志文件中提取数据库查询,并在psql中使用“analyze explain”运行它。