如何找到 Django 模型中所有名称的最新匹配项?

发布于 2025-01-01 06:26:07 字数 286 浏览 0 评论 0原文

我有一个看起来像这样的 django 模型:

class MyModel(Model):
    name = CharField(...)
    version = IntegerField(...)
    other_stuff = ...

    unique_together = ('name', 'version')

我希望能够查询每个名称的所有最新版本,但忽略任何给定名称的所有旧版本。

这对于 Django 模型来说可能吗?如果是这样,那会是什么样子?

I have a django model that looks like this:

class MyModel(Model):
    name = CharField(...)
    version = IntegerField(...)
    other_stuff = ...

    unique_together = ('name', 'version')

I want to be able to query for all of the most recent versions of each name, but omitting all older versions for any given name.

Is this possible with Django models? If so, what would that look like?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

情痴 2025-01-08 06:26:07

我不确定您是否可以仅使用 Django ORM 的聚合功能立即做到这一点。不管怎样,我认为这个结构正在尖叫这样的建模:

class MyModel(Model):
    name = CharField(...)
    some_stuff = ...

class Version(Model):
    number = IntegerField(...)
    my_model = ForeignKey(MyModel, ...)
    other_stuff = ...

所以你可以这样做来获取每个MyModel的最新版本:

>>> from django.db.models import Max
>>> MyModel.objects.annotate(highest_version = Max('version__number'))

I'm not sure you can do that right away just with the aggregation features of the Django ORM. Anyway, I think this structure is screaming a modeling like this:

class MyModel(Model):
    name = CharField(...)
    some_stuff = ...

class Version(Model):
    number = IntegerField(...)
    my_model = ForeignKey(MyModel, ...)
    other_stuff = ...

So you could do this to get the newest version of every MyModel:

>>> from django.db.models import Max
>>> MyModel.objects.annotate(highest_version = Max('version__number'))
屌丝范 2025-01-08 06:26:07

我相信您需要按名称分组,然后在每个组上进行选择。我自己从未使用过这个,但是这个问题可能会提供一些关于如何做到这一点的见解。

更新:看来我的代码是正确的,但是虽然它应该适用于您的特定情况,但我还不知道如何获取同一查询中的其他字段(假设您不仅想要版本数字,但其他东西也一样 - 这个解决方案不起作用):

from django.db.models import Max
MyModel.objects.values('name').annotate(Max('version'))

# Will return something like:
# [{'name':'a', 'version__max':3}, {'name':'b', 'version__max':2}, ...]

如果您使用 Django 1.4 和 PostgreSQL,您可能可以使用 distinct 方法:

MyModel.objects.order_by('name', '-version').distinct('name')

I believe you need to group by name, then select on each group. Never used this myself, but this question may offer some insights on how to do it.

Update: it seems I got the code right, but while it should work for your specific case I don't know yet how to get the other fields in the same query (suppose you wanted not only the version numbers but the other stuff too - this solution won't work):

from django.db.models import Max
MyModel.objects.values('name').annotate(Max('version'))

# Will return something like:
# [{'name':'a', 'version__max':3}, {'name':'b', 'version__max':2}, ...]

If you're using Django 1.4 and PostgreSQL, you might be able to do that using the distinct method:

MyModel.objects.order_by('name', '-version').distinct('name')
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文