过滤Django的最新记录

时间:2015-06-01 22:04:07

标签: python django

编写我的第一个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)

2 个答案:

答案 0 :(得分:3)

如果您使用的是PostgreSQL,可以组合使用distinctorder_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()]

这为您数据库中的每个应用添加了一个查询,但是非常具有表现力,有时可维护性和可读性比性能更重要。