简体   繁体   English

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

[英]How to optimize DRF number queries when using properties in serializers fields?

I am working on a DRF API and I am not completely familiar with django properties.我正在研究 DRF API,但我并不完全熟悉 django 属性。

The DB relationships are classic.数据库关系是经典的。 Companies have different jobs to which candidates can apply.公司有不同的职位可供候选人申请。 Each job has several matches, match being a joined table between a job and a candidate.每个职位都有多个匹配项,匹配项是职位和候选人之间的连接表。 Matches have different statuses representing different phases of an application process.匹配具有不同的状态,代表申请过程的不同阶段。

So here is the deal: I am using a drf viewset to get data from the api.所以这是交易:我正在使用 drf 视图集从 api 获取数据。 This viewset uses a serializer to get specific fields, specifically the number of matches per status for a job.此视图集使用序列化程序来获取特定字段,特别是作业每个状态的匹配数。 The simplified version of the serializer looks something like this.序列化程序的简化版本看起来像这样。

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',
        )

The job__xxx fields are using the decorator @property , for instance: job__xxx字段使用装饰器@property ,例如:

@property
def job__nb_matches_offre(self):
    return self.matches.filter(current_status__step_name='Offre').count()

The problem is each time I add one of these properties to my serializer's fields, the number of DB queries increases significantly.问题是每次我将这些属性之一添加到我的序列化程序的字段时,数据库查询的数量都会显着增加。 This is of course due to the fact that each property calls the DB multiple times.这当然是因为每个属性都会多次调用数据库。 So here is my question:所以这是我的问题:

Is there a way to optimize the number of queries made to the DB, either by changing something in the serializer or by getting the number of matches for a specific status in a different manner?有没有办法通过更改序列化程序中的某些内容或通过以不同方式获取特定状态的匹配数来优化对数据库的查询数量?

I have had a look at select_related and prefetch_related .我看过select_relatedprefetch_related This allows me to reduce the numbers of queries when getting information about the company but not really for the number of matches.这使我能够在获取有关公司的信息时减少查询的数量,但实际上并不能减少匹配的数量。

Any help is greatly appreciated:)任何帮助是极大的赞赏:)

What you want is to annotate your queryset with these values which will result in the database doing all the counting in just one query.你想要的是用这些值注释你的查询集,这将导致数据库在一个查询中完成所有计数。 The result is significantly faster than your current solution.结果明显快于您当前的解决方案。

Example:例子:

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()

The resulting queryset will contain Job objects that have the properties job_obj.nb_matches_offre and job_obj.nb_matches_entretiens with the count.生成的查询集将包含具有属性job_obj.nb_matches_offrejob_obj.nb_matches_entretiens以及计数的 Job 对象。

See also https://docs.djangoproject.com/en/3.0/topics/db/aggregation/另见https://docs.djangoproject.com/en/3.0/topics/db/aggregation/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM