编写我的第一个Django应用程序,该应用程序从其他应用程序获取消息并存储有关它们的报告。
由于我希望可以改进的以下逻辑,它表现得非常慢,但我很难找到一种方法来完成循环。
基本上我只是试图浏览所有应用程序(大约有500个独特的应用程序)并获取每个应用程序的最新报告。这是我的模型和功能:
class App(models.Model):
app_name = models.CharField(max_length=200)
host = models.CharField(max_length=50)
class Report(models.Model):
app = models.ForeignKey(App)
date = models.DateTimeField(auto_now_add=True)
status = models.CharField(max_length=20)
runtime = models.DecimalField(max_digits=13, decimal_places=2,blank=True,null=True)
end_time = models.DateTimeField(blank=True,null=True)
def get_latest_report():
""" Returns the latest report from each app """
lset = set()
## get distinct app values
for r in Report.objects.order_by().values_list('app_id').distinct():
## get latest report (by date) and push in to stack.
lreport = Report.objects.filter(app_id=r).latest('date')
lset.add(lreport.pk)
## Filter objects and return the latest runs
return Report.objects.filter(pk__in = lset)
答案 0 :(得分:3)
如果您使用的是PostgreSQL,可以组合使用distinct
和order_by
,为您提供每个应用的最新报告
Report.objects.order_by('-date').distinct('app')
如果您使用的数据库不支持DISTINCT ON
子句,例如MySQL,并且您不介意更改Report
模型的默认顺序,则可以使用{{3}将500多个查询减少到2(但是这个方法将使用更多的内存,因为它将加载每个报告)
class Report(models.Model):
# Fields
class Meta:
ordering = ['-date']
def get_latest_report():
latest_reports = []
for app in App.objects.all().prefetch_related('report_set'):
try:
latest_reports.append(app.report_set.all()[0])
except IndexError:
pass
return latest_reports
答案 1 :(得分:3)
如果您不担心对数据库中的每个应用程序执行查询,可以这样尝试:
def get_latest_report():
""" Returns the latest report from each app """
return [app.report_set.latest('date') for app in App.objects.all()]
这为您数据库中的每个应用添加了一个查询,但是非常具有表现力,有时可维护性和可读性比性能更重要。