Django ORM 使用字典数组排除记录

Django ORM exclude records using an array of dictionaries

我有类似的代码 return 来自 table 的所有条目:

all_entries = Entry.objects.all()

我有以下数组:

exclusion_list = [
  {
    "username": "Tom",
    "start_date": 01/03/2019,
    "end_date": 29/02/2020,
  },
  {
    "username": "Mark",
    "start_date": 01/02/2020,
    "end_date": 29/02/2020,
  },
  {
    "username": "Pam",
    "start_date": 01/03/2019,
    "end_date": 29/02/2020,
  }
]

我想排除 Tom 从“01/03/2019”到“29/02/2020”的所有记录,从“01/02/2020”到“29/02/2020”的所有“Mark”记录以及 Pam 从“01/03/2019”到“29/02/2020”的所有记录

我想循环执行此操作,所以我认为我应该执行以下操作:

for entry in all_entries:
    filtered_entry = all_entries.exclude(username=entry.username).filter(date__gte=entry.start_date, date__lte=entry.end_date)

这种做法正确吗?我是 Django ORM 的新手。有没有更好更高效的解决方案?

感谢您的帮助

是的,你可以用一个循环来做到这一点。

这会生成一个查询,其 WHERE-clause 在循环的每个周期中都会得到扩展。但是要做到这一点,你必须使用你之前循环的过滤查询集:

filtered_entry = all_entries

for exclude_entry in exclusion_list:
   filtered_entry = filtered_entry.exclude(username=exclude_entry.username, date__gte=exclude_entry.start_date, date__lte=exclude_entry.end_date)
笔记
  • 使用查询集的相同引用进一步限制每个循环周期的结果
  • 要使用与 AND 连接的多个条件,只需在 exclude() 中写入多个关键字参数(查看文档 [此处][1])
  • 请注意,这可能会导致很大 WHERE-clause 并且您的数据库可能存在限制

所以如果你的exclude_list不是太大,我觉得你可以放心使用。

如果您的 exclude_list 增长,最好将您的 exclusion_list 保存在数据库本身中。有了这个 ORM 可以生成子查询而不是单个值。举个例子:

exclusion_query = ExclusionEntry.objects.all().values('username')

filtered = all_entries.exclude(username__in=exclusion_query)
  [1]: https://docs.djangoproject.com/en/3.1/topics/db/queries/#retrieving-specific-objects-with-filters