如何通过django属性或其他解决方案订购

时间:2018-07-01 22:31:08

标签: python django

好吧,所以我是django的新手,不确定我是否正确地解决了这个问题,但是这里是:

我有一类事件和事件源,您可以为一个事件提供多个源。

class Incident(models.Model):
    iid = models.IntegerField(primary_key=True)
    person = models.ForeignKey('Person', on_delete=models.SET_NULL, null=True)

    @property
    def first_reporteddate(self):
        return self.source_set.aggregate(first=Min('datereported'))['first']


class Source(models.Model):

    sid = models.IntegerField(primary_key=True)
    incident = models.ForeignKey('Incident', on_delete=models.SET_NULL, null=True)
    url = models.TextField(validators=[URLValidator()])
    datereported= models.DateTimeField(null=True, blank=True) 

在创建新事件时,我想要求还创建一个源。我想为用户提供按ID,人员或最早报告的事件源日期对事件模型进行排序的选项。

是否可以通过属性对模型进行分类(在本例中为first_reporteddate),还是需要将其作为字段?我应该如何构建这个过程?

1 个答案:

答案 0 :(得分:1)

  

是否可以通过属性对模型进行分类(在这种情况下为first_reporteddate),还是需要将其作为字段?我应该如何构建这个过程?

您无法在数据库级别对属性进行排序。您可以使用Python执行此操作,但这通常效率不高。

您可以 做的是构造一个注释。例如:

from django.db.models import Min

Incident.objects.annotate(
    first_reporteddate = Min('source__datereported')
).order_by(
    'first_reporteddate'
)

因此,在这里,我们让数据库对每一个 Incident进行注释(以及那些在.filter(..)情况下未被过滤掉的注释),然后通过此注释进行排序。

如果属性的逻辑太复杂而无法在数据库级别进行处理(如果逻辑非常复杂,或者需要Web服务,文件系统,则可能很难,甚至不可能)。您可以使用Python本身进行排序。但是(a)这通常效率不高,并且(b)结果是一个列表,因此不再是可以进一步过滤的查询集。例如:

sorted(Incident.objects.all(), key=lambda x: x.first_reporteddate)

这里的结果是一个包含Incident实例的 all 列表,如果您对第一个,前三个等感兴趣,则通常效率低下。此外,如果first_reporteddate返回None,这将引发错误,尽管您可以编写额外的逻辑来规避此问题。