好吧,所以我是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),还是需要将其作为字段?我应该如何构建这个过程?
答案 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
,这将引发错误,尽管您可以编写额外的逻辑来规避此问题。