合并两个 Django 查询集并删除共享公共值的重复对象
Merge two Django query sets and deduplicate objects sharing a common value
我有一个使用分段库的 Django 项目,需要合并两个查询集并对生成的查询集进行重复数据删除,这让我摸不着头脑。
not_segments = Page.objects.all().no_segments()
(释义)给我排除了部分页面的页面。
only_segments = Segment.objects.get_queryset().for_user(user=user)
(转述)给我来自同一模型的分段页面对象,但当然有重叠。
not_segments = Page 1, Page 2, Page 3, Page 4
only_segments = Page 2 (for user), Page 4 (for user)
所以假设模型中有一个 guid 字段,它不是强制唯一的,而是在根页面和它的段子页面之间的值相同。如果 only_segments
中存在具有相同 guid 的对象,我如何在合并它们时比较两个查询集的对象并从 not_segments
中省略对象?
获得 queryset = Page 1, Page 2 (for user), Page 3, Page 4 (for user)
的预期结果
如果 not_segments
和 only_segments
是来自同一模型的记录,您可以将它们与 OR (|) operator 组合起来生成另一个查询集。结果将是独特的项目。
deduplicated_qs = not_segments | only_segments
如果它们是来自不同模型的记录,那么您可以通过跟踪已添加的 guid 来手动过滤掉重复值,以便不再重新添加它们。
import itertools
# To simplify the example, this is just a raw Python-class. In reality, this would be the Django-model-class.
class Page:
def __init__(self, guid, value):
self.guid = guid
self.value = value
class Segment:
def __init__(self, guid, other_value):
self.guid = guid
self.other_value = other_value
only_segments = [
Page(2, 'A'),
Page(4, 'B'),
]
not_segments = [
Segment(1, 'C'),
Segment(2, 'D'),
Segment(3, 'E'),
Segment(4, 'F'),
]
added_guids = set()
deduplicated_pages = list()
for page_or_segment in itertools.chain(only_segments, not_segments):
if page_or_segment.guid in added_guids:
continue
added_guids.add(page_or_segment.guid)
deduplicated_pages.append(page_or_segment)
for page in deduplicated_pages:
print(type(page), page.__dict__)
输出
<class '__main__.Page'> {'guid': 2, 'value': 'A'}
<class '__main__.Page'> {'guid': 4, 'value': 'B'}
<class '__main__.Segment'> {'guid': 1, 'other_value': 'C'}
<class '__main__.Segment'> {'guid': 3, 'other_value': 'E'}
我有一个使用分段库的 Django 项目,需要合并两个查询集并对生成的查询集进行重复数据删除,这让我摸不着头脑。
not_segments = Page.objects.all().no_segments()
(释义)给我排除了部分页面的页面。
only_segments = Segment.objects.get_queryset().for_user(user=user)
(转述)给我来自同一模型的分段页面对象,但当然有重叠。
not_segments = Page 1, Page 2, Page 3, Page 4
only_segments = Page 2 (for user), Page 4 (for user)
所以假设模型中有一个 guid 字段,它不是强制唯一的,而是在根页面和它的段子页面之间的值相同。如果 only_segments
中存在具有相同 guid 的对象,我如何在合并它们时比较两个查询集的对象并从 not_segments
中省略对象?
获得 queryset = Page 1, Page 2 (for user), Page 3, Page 4 (for user)
如果 not_segments
和 only_segments
是来自同一模型的记录,您可以将它们与 OR (|) operator 组合起来生成另一个查询集。结果将是独特的项目。
deduplicated_qs = not_segments | only_segments
如果它们是来自不同模型的记录,那么您可以通过跟踪已添加的 guid 来手动过滤掉重复值,以便不再重新添加它们。
import itertools
# To simplify the example, this is just a raw Python-class. In reality, this would be the Django-model-class.
class Page:
def __init__(self, guid, value):
self.guid = guid
self.value = value
class Segment:
def __init__(self, guid, other_value):
self.guid = guid
self.other_value = other_value
only_segments = [
Page(2, 'A'),
Page(4, 'B'),
]
not_segments = [
Segment(1, 'C'),
Segment(2, 'D'),
Segment(3, 'E'),
Segment(4, 'F'),
]
added_guids = set()
deduplicated_pages = list()
for page_or_segment in itertools.chain(only_segments, not_segments):
if page_or_segment.guid in added_guids:
continue
added_guids.add(page_or_segment.guid)
deduplicated_pages.append(page_or_segment)
for page in deduplicated_pages:
print(type(page), page.__dict__)
输出
<class '__main__.Page'> {'guid': 2, 'value': 'A'}
<class '__main__.Page'> {'guid': 4, 'value': 'B'}
<class '__main__.Segment'> {'guid': 1, 'other_value': 'C'}
<class '__main__.Segment'> {'guid': 3, 'other_value': 'E'}