【问题标题】:Query a list with the top N elements in each group查询每组前 N 个元素的列表
【发布时间】:2020-05-29 17:22:54
【问题描述】:

假设我有两个模型:

class Result(models.Model):
    b = foreignKey(ModelB)

class ModelB(models.Model):
    code = models.CharField(...)

我需要的是只保留与每个模型相关的 N 个最新结果并删除其余的。表 ModelB 和 Result 确实可以有很多记录。 有没有办法我可以使用 django ORM 执行此操作而无需创建循环?

[编辑]- 示例

ModelB objs: [(1, [result1, result2, result3, result4]), (2, [result10, result11, result12])]

Result objs: [(result1), (result2), (result3), (result4), (result10), (result11), (result12)]

假设我只想保留每个 Modelb 子集中的 2 个最新结果,其余的应该如下

ModelB objs:  [(1, [result4, result3]), (2, result12, result11)]
Result objs: [(result3), (result4), (result11), (result12)]

【问题讨论】:

    标签: python django python-3.x orm django-orm


    【解决方案1】:

    我会在模型中添加一个created 字段,以便您知道对象的创建时间。然后,您可以通过此命令查找最新的 N 实例。

    class Result(models.Model):
        b = foreignKey(ModelB)
        created = models.DateTimeField(auto_now_add=True)
        # modified = models.DateTimeField(auto_now=True)
    
        class Meta:
            get_latest_by = "created"
    

    就删除对象而言,您可以执行以下操作;

    n = 10
    results = Result.objects.all().count()
    
    if results > n:
        all_results = Result.objects.all()
        keep = all_results[n:]
        keep_ids = keep.values_list('id', flat=True)
        all_results.exclude(id__in=keep_ids).delete()
    

    可能还值得注意的是模型元的get_latest_by 属性,它允许您定义如何识别最新实例。

    【讨论】:

    • 感谢您的回复,但没有从每个子集中删除。对不起,我想我错过了一个例子,所以我编辑将它添加到问题中。
    • @SaturninoMateus 根据您添加的内容,您有一个元组列表。因此,您必须每次遍历列表并从结果中删除您不想要的内容。
    • 那只是为了说明。我只有模型,我正在尝试找到一种更有效的方法,而无需手动迭代。
    • @SaturninoMateus 如果您只有模型,那么请实施我说明的概念来控制您保留的对象数量。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-11
    • 1970-01-01
    • 1970-01-01
    • 2020-11-05
    相关资源
    最近更新 更多