在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
相关产品推荐
相关产品推荐

