【问题标题】:Merge two Django query sets and deduplicate objects sharing a common value合并两个 Django 查询集并删除共享相同值的对象
【发布时间】:2021-10-24 07:09:40
【问题描述】:

我有一个使用分段库的 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_segmentsPage 对象的查询集,而only_segmentsSegment 对象的查询集?
  • 它们返回相同模型的对象,只是通过不同的中间方法到达不同的对象列表。

标签: django filter django-queryset


【解决方案1】:

如果 not_segmentsonly_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'}

【讨论】:

  • 谢谢,这就是我所缺少的......合并它们的最有效方法而不需要对它们都使用 for 循环,随着对象数量随着时间的推移而增加,我担心效率。跨度>
猜你喜欢
  • 1970-01-01
  • 2016-06-20
  • 2017-12-04
  • 2021-12-17
  • 1970-01-01
  • 2019-08-11
  • 2010-10-17
  • 2013-02-17
  • 2021-11-10
相关资源
最近更新 更多