You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Django中遵循DRY原则,以Pythonic方式合并属性查询字典的实现方案

嘿,这个需求太贴合实际业务场景啦!我来给你分享两种目标结构的Pythonic实现方式,还会结合你的Django模型场景给出更高效、符合DRY原则的方案~

方案1:转换为列表嵌套字典结构

如果你需要得到列表包裹的字典结构,可以通过一个临时字典来分组聚合属性值,逻辑清晰且避免重复代码:

original_queries = [
    { "primary_attribute__name": "Color", "primary_attr_values__name": "Red" },
    { "primary_attribute__name": "Color", "primary_attr_values__name": "Green" }
]

# 用临时字典分组,自动合并相同属性名的条目
grouped_dict = {}
for item in original_queries:
    attr_name = item["primary_attribute__name"]
    value = item["primary_attr_values__name"]
    
    # 首次遇到该属性时初始化结构
    if attr_name not in grouped_dict:
        grouped_dict[attr_name] = {
            "primary_attribute__name": attr_name,
            "primary_attr_values__name": []
        }
    grouped_dict[attr_name]["primary_attr_values__name"].append(value)

# 额外添加Yellow值
grouped_dict["Color"]["primary_attr_values__name"].append("Yellow")

# 转换为目标列表格式
result_list = list(grouped_dict.values())
print(result_list)

方案2:转换为属性名作为键的嵌套字典(更推荐)

这种结构的优势是查找效率更高(直接通过属性名定位,时间复杂度O(1)),也更符合我们对“属性-值集合”的直观认知,实现起来同样简洁:

original_queries = [
    { "primary_attribute__name": "Color", "primary_attr_values__name": "Red" },
    { "primary_attribute__name": "Color", "primary_attr_values__name": "Green" }
]

primary_attribute = {}
for item in original_queries:
    attr_name = item["primary_attribute__name"]
    value = item["primary_attr_values__name"]
    
    if attr_name not in primary_attribute:
        primary_attribute[attr_name] = { "primary_attr_values__name": [] }
    primary_attribute[attr_name]["primary_attr_values__name"].append(value)

# 添加Yellow值
primary_attribute["Color"]["primary_attr_values__name"].append("Yellow")

print(primary_attribute)

结合Django模型的最优实现(极致符合DRY原则)

既然你已经有对应的Django模型,其实完全可以跳过“先查零散数据再转换”的步骤,直接通过数据库聚合得到目标结构——这才是最符合DRY原则的做法,减少冗余的代码和数据处理:

from django.db.models import Collect

# 假设你已经获取了目标Product实例
target_product = Product.objects.get(id=1)

# 直接从数据库聚合同一属性下的所有值
aggregated_attrs = VariantAttributes.objects.filter(
    variant__product=target_product
).values(
    'primary_attr__name'  # 按属性名分组
).annotate(
    value_list=Collect('primary_attr_value__name')  # 聚合该属性下的所有值为列表
)

# 转换为你需要的嵌套字典结构
primary_attribute = {
    item['primary_attr__name']: {'primary_attr_values__name': item['value_list']}
    for item in aggregated_attrs
}

这里用到的Collect是Django 2.0+支持的聚合函数,能直接将同一分组下的字段值收集为列表,一步到位完成数据聚合,完全不需要额外的字典转换操作。

总的来说,第二种嵌套字典结构更适合后续业务操作,而直接从数据库聚合的方式则是最高效、最符合DRY原则的方案~

内容的提问来源于stack exchange,提问作者Madhav Dhungana

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 13:47:28