基于Djang中的2层深层一对一关系计算多个带注释的特性

2024-09-28 05:16:17 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在寻找一种更为优化的方法来获取模型记录上的注释值,为了计算这些值,我必须在基础模型上注释一组记录,这需要使用它从其上的一组记录计算的值。以下是模型的结构:

class Employee(models.Model):
    first_name = models.CharField()
    last_name = models.CharField()
    client = models.ForeignKey("app.Client")


class DocumentTemplate(models.Model):
    name = models.CharField()
    warning_days = models.IntegerField()
    client = models.ForeignKey("app.Client")


class EmployeeDocument(models.Model):
    document_template = models.ForeignKey("app.DocumentTemplate")
    employee = models.ForeignKey("app.Employee")

    @property
    def current_document(self):
        return self.documents.latest("date_added")

    @property
    def expiration_date(self):
        current_document = self.current_document

        if not current_document:
            return None

        return current_document.expiration_date

    @property
    def near_expiration_date(self):
        current_document = self.current_document

        if not current_document and current_document.expiration_date is not None:
            return None

        return currnet_document.expiration_date - timedelta(days=self.documenttemplate.warning_days)


class EmployeeDocumentInstance(models.Model):
    employee_document = models.ForeignKey("app.EmployeeDocument", related_name="documents")

    date_added = models.DateTimeField(auto_now_add=True)
    expiration_date = models.DateField(null=True)
    document_instance_date = models.DateField(null=True)

    is_a_failure = models.BooleanField(default=False)

当我检索Employee记录时,我通常还需要知道每个员工记录的以下信息:

  • 我的EmployeeDocuments中是否有任何一个的EmployeeDocumentInstance为零
  • 我的EmployeeDocument.expiration_date值中有多少小于今天的日期
  • 我的EmployeeDocument.near_expiration_date值中有多少小于今天的日期

在检索员工记录时,我实际上没有使用这些属性方法来访问当前文档的current_documentexpiration_date,因为它最终是大量的单个查询。我将这些属性放在这个示例中,以说明我们如何将添加的最新实例视为当前EmployeeDocument

我走过的道路是在员工记录上注释这些内容。在获取员工记录时,我使用QuerySet.annotate注释has_missing_documentsexpired_document_countnear_expiration_document_count的值

我发现,这些注释虽然有效,但会显著降低员工列表查询的速度。如果我只注释其中一个属性,它仍然非常快,但我添加的每个属性似乎都会在查询中添加一到两个属性,这是不可接受的。。。尤其是当我只获取100条员工记录时

我真正想知道的是,如何通过Django和Postgresql有效地获取以下类型的数据:

class Employee:
    # employee properties from the Employee table
    has_documents_with_no_instances
    count_of_documents_where_latest_instance_is_expired
    # ^^^ I will need this for near expiration and failure status of those instances as well, but this should illustrate what I am looking for

一个小背景故事:当我被介绍到这个代码库时,每当添加或编辑一个新的文档实例时,通过计算和存储“计算”类型值就可以实现这些功能。。但我一直在尽我所能远离这种方法,因为这会产生不准确的结果。问题是,现在它是准确的,因为没有清理“触发器”,但现在它很慢-非常慢(就像100条记录慢了10秒)-任何帮助都将不胜感激


Tags: selfappdatereturnmodels记录员工employee

热门问题