合并多个django的queryset

需求概要:

有个iterm,他有一个属性是类型(只有主和副),iterm是自关联。

有一个需求是这样的,无论是哪个iterm点进来,

如果这个iterm是主:  要展示当前iterm和iterm所有的子iterm

如果这个iterm是副:  要展示其主iterm和主iterm所有的子iterm

 

代码如下:

current_iterm = self.get_object()

# 先找到主
if current_iterm.version_type == const.VERSION_TYPE_SUB:
    main_version_iterm = iterms.objects.get(pk=current_iterm.parent_id)
elif current_iterm.version_type == const.VERSION_TYPE_MAIN:
    main_version_iterm = current_iterm
else:  # 找不到iterm
    raise SHException(errors.ERR_INVALID_VALUE, 'Invalid uuid.')

# 获取主版本、副版本的queryset
main_version_iterm_qs = iterms.objects.filter(pk=main_version_iterm.uuid)
sub_version_iterms_qs = iterms.objects.filter(parent_id=main_version_iterm.uuid).all()

现在 我们有了两个queryset,一个main_version_iterm_qs, 一个sub_version_iterm_qs

首先我们可以使用 `|` 管道符 来合并两个queryset。

data = main_version_iterm_qs | sub_version_iterms_qs

# 使用list源码,将详情接口返回list
page = self.paginate_queryset(data)
if page is not None:
    serializer = self.get_serializer(page, many=True)
    return self.get_paginated_response(serializer.data)

serializer = self.get_serializer(data, many=True)

但是,我们使用分页serializer后发现顺序变了。

这样不符合将main放在前面的需求,pass。

然后我们考虑使用chain,就是itertools里面的链,将可迭代对象迭代组合成一个列表

data = chain(main_version_iterm_qs, sub_version_iterms_qs)

但是呢,这样将data传入serializer里面会提示:

object of type 'itertools.chain' has no len()

没有len方法。

所以:重新使用列表生成式重新赋值data,这样就可以了。


# 将主版本和副版本拼一起,主版本永远在最前面
data = chain(main_version_iterm_qs, sub_version_iterms_qs)
data = [iterm for iterm in data]

# 使用list源码,将详情接口返回list
page = self.paginate_queryset(data)
if page is not None:
    serializer = self.get_serializer(page, many=True)
    return self.get_paginated_response(serializer.data)

serializer = self.get_serializer(data, many=True)

PS: 这样是将所有的数据库数据拿到内存中再分页,消耗还是比较大,求有更好的建议!

既然可以用chain,当然也有更原始的方法。
 

data_list = []

data_list.extend(main_version_work_qs)

data_list.extend(sub_version_work_qs)

然后使用序列化 分页就可以完成了。

 

PS: 这种方法是将所有的数据库数据拿到内存中再分页,消耗还是比较大,求有更好的建议!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天马行空波

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值