【问题标题】:Check if each value within list is present in the given Django Model Table in a SINGLE query检查列表中的每个值是否存在于单个查询中的给定 Django 模型表中
【发布时间】:2022-01-13 21:12:53
【问题描述】:

假设我想实现这个通用函数:

def do_exist(key:str, values:list[any], model: django.db.models.Model) -> bool

在 SINGLE 查询中检查所有给定值是否存在于给定模型的名为 key 的列中。 我已经实现了这样的东西

from django.db.models import Exists
def do_exist(key, values, model):
    chained_exists = (Exists(model.objects.filter(F(key)=value)) for value in values)
    qs = model.objects.filter(*chained_exists).values("pk")[:1] 
    # Limit and values used for the sake of less payload
    return len(qs) > 0

它会生成一个非常有效的 SQL 查询,但让我害怕的是,如果我尝试将评估方法调用附加到 qs,比如 .first() 而不是 [:1] 或 .exists(),MYSQL 连接就会断开。 有没有人有更优雅的方法来解决这个问题?

【问题讨论】:

  • 我不是 100% 确定我是否理解您的问题,但是如果您想在 Django 中进行过滤,您可以使用带有查询集的 id__in 查询来根据 ID 列表过滤查询集。

标签: python mysql django django-models


【解决方案1】:

如果您知道您正在传递 N pks,那么由这些 pks 过滤的 count() 查询应该恰好具有 N 结果。

def do_exist(model, pks):
    return model.objects.filter(pk__in=pks).count() == len(pks)

【讨论】:

  • 那么不唯一的字段呢?
  • 主键总是唯一的。那将是一个不同的问题。但是,对于非唯一值,您可以在 .count() 之前添加 .distinct()。
【解决方案2】:
qs = MyModel.objects.filter(id__in=pks)

这为您提供了一个查询集,您可以将 .all() 等应用到

【讨论】:

  • 您的计数始终可以在查询结束时完成,但您表示您的问题是使用 .all() 评估您的查询
【解决方案3】:

在 Django 中,您可以使用带有查询集的 id__in 查询来根据 ID 列表过滤查询集。

results = Model.objects.filter(id__in = pks)

【讨论】:

  • 慢慢读一遍
【解决方案4】:
res = MyModel.objects.filter(id__in=pks)

【讨论】:

  • 慢慢读一遍
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-10-24
  • 2011-11-20
  • 2016-11-22
  • 2020-06-15
  • 1970-01-01
  • 2021-01-05
  • 1970-01-01
相关资源
最近更新 更多