Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/308.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 是否可以创建Django查询集来执行此复杂查询?_Python_Mysql_Django_Django Queryset - Fatal编程技术网

Python 是否可以创建Django查询集来执行此复杂查询?

Python 是否可以创建Django查询集来执行此复杂查询?,python,mysql,django,django-queryset,Python,Mysql,Django,Django Queryset,假设我有以下Django类: class MyModel(models.Model): a = models.IntegerField() created_ts = models.DateTimeField(default=datetime.utcnow, editable=False) def __str__(self): return "<%s %s>" % ( self.__class__.__name__,

假设我有以下Django类:

class MyModel(models.Model):
    a = models.IntegerField()
    created_ts = models.DateTimeField(default=datetime.utcnow, editable=False)

    def __str__(self):
        return "<%s %s>" % (
            self.__class__.__name__,
            "; ".join(
                [
                    "ID: %s" % self.pk,
                    "a: %s" % self.a,
                    "created_ts: %s" % self.created_ts,
                ]
            )
        )

不知道如何使用单个查询集进行查询,但是如果您愿意以不使用raw为代价进行更多查询,那么您可以这样做

from django.db.models import Max
max_ts_queryset = MyModel.objects.values('a').order_by('a').annotate(max_ts=Max('created_ts'))
要获得a的每个值的最大ts,只需使用以下内容循环

final_list = {}
for obj in max_ts_queryset:
    final_list[obj['a']] = MyModel.objects.get(a=obj['a'], created_ts=obj['max_ts']

return final_list

这不是最直接的答案,但希望能有所帮助:

然后你可以用


我自己还没有运行这个查询,所以它可能有语法错误,但你知道了。

如果你是在Postgres上,这将起作用。如果您使用的是MySQL或sqlite,则无法正常工作

MyModel.objects.order_by('a', '-created_ts').distinct('a')
编辑:哇,刚刚看到你在MySQL上

这将帮助您

from django.db.models import Count, Max
MyModel.objects.values('a').annotate(count=Count("a"),latest_date=Max('created_ts'))
表中的数据

    a              created_ts
    -             -----------
    1 2015-09-08 20:05:51.144321+00:00
    1 2015-09-08 20:08:40.687936+00:00
    3 2015-09-08 20:08:58.472077+00:00
    2 2015-09-08 20:09:08.493748+00:00
    2 2015-09-08 20:10:20.906069+00:00
输出

[
    {'count': 2, 'latest_date': datetime.datetime(2015, 9, 8, 20, 8, 40, 687936, tzinfo=<UTC>), 'a': 1},
    {'count': 2, 'latest_date': datetime.datetime(2015, 9, 8, 20, 10, 20, 906069, tzinfo=<UTC>), 'a': 2},
    {'count': 1, 'latest_date': datetime.datetime(2015, 9, 8, 20, 8, 58, 472077, tzinfo=<UTC>), 'a': 3}
]
[
{'count':2,'latest_date':datetime.datetime(2015,9,8,20,8,40,687936,tzinfo=),'a':1},
{'count':2,'latest_date':datetime.datetime(2015,9,8,20,10,20906069,tzinfo=),'a':2},
{'count':1,'latest_date':datetime.datetime(2015,9,8,20,8,58472077,tzinfo=),'a':3}
]
从中,由于查询集的结果是一个查询集,因此您应该能够如下链接:

{
    1: <MyModel ID: 1; a: 1; created_ts: 2004-11-08 06:01:00>,
    5: <MyModel ID: 2; a: 5; created_ts: 2004-11-05 08:01:32>,
    3: <MyModel ID: 3; a: 3; created_ts: 2004-11-04 11:01:42>,
    0: <MyModel ID: 4; a: 0; created_ts: 2004-11-03 06:12:10>,
}

MyModel.objects.order_by('created_ts')。distinct('a')

您的问题几乎与您之前的问题完全相同:

因此,我将使用我的前一部分回答:

注意,这只需要一个SQL请求,正如您在查询前后打印len(django.db.connection.querys)所看到的那样


但是,请注意,后一种解决方案只有在您创建的属性保证唯一的情况下才有效,这可能不是您的情况。

您使用的是什么数据库后端?MySQL不支持按字段区分(PostgreSQL支持)。正如我所知,如果不使用原始SQL,就没有“直截了当”的方法来做你想做的事情。后端是mysql。是的,它不支持“按字段区分”。解决办法是什么?如果必要的话,我宁愿做多个查询,而不是编写原始SQL。有趣的是,这几乎是我从中得到它的复制品。如果你看看那里,你会发现我用另一种方法做了一些工作,使用蛮力python,直到我发现了这种方法。这样做时,添加到原始解决方案的链接才是公平的。
[
    {'count': 2, 'latest_date': datetime.datetime(2015, 9, 8, 20, 8, 40, 687936, tzinfo=<UTC>), 'a': 1},
    {'count': 2, 'latest_date': datetime.datetime(2015, 9, 8, 20, 10, 20, 906069, tzinfo=<UTC>), 'a': 2},
    {'count': 1, 'latest_date': datetime.datetime(2015, 9, 8, 20, 8, 58, 472077, tzinfo=<UTC>), 'a': 3}
]
MyClass.objects.filter(
    created_ts__in=MyClass.objects.values(
        "a"
    ).annotate(
        created_ts=models.Max(
            "created_ts"
        )
    ).values_list("created_ts", flat=True)
)