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
我有类似的代码 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