【问题标题】:get all the related detail of a a model object by using django ORM queries?通过使用 django ORM 查询获取模型对象的所有相关细节?
【发布时间】:2020-01-31 17:41:36
【问题描述】:

这些是我的 django 模型。

db 模型说明:
thinkpadlaptop subcategoryequipment .and laptop subcategory 有一个名为 electronicscategory
现在笔记本电脑可以有很多attributes,比如processor,ram,color,screen_size

问题:
找出所有具有 category_id =1equipment 和 theirequipment detail ,subcategory_name and attribute names,value

型号:

class Category(models.Model):
    category_id = models.AutoField(primary_key=True, default=None)
    category_name = models.CharField(max_length=15, unique=True)
    created_at = models.DateTimeField(auto_now_add=True)
    last_modified = models.DateTimeField(auto_now=True)

    def __str__(self):
        return str(self.category_id)+","+self.category_name

    class Meta:
        db_table = "category"


class Subcategory(models.Model):
    subcategory_id = models.AutoField(primary_key=True, default=None)
    category = models.ForeignKey(
        Category, on_delete=models.CASCADE, related_name="category_subc", verbose_name="category_id")
    subcategory_name = models.CharField(max_length=15, unique=True)
    created_at = models.DateTimeField(auto_now_add=True)
    last_modified = models.DateTimeField(auto_now=True)

    def __str__(self):
        return str(self.subcategory_id)+","+self.subcategory_name

    class Meta:
        db_table = "subcategory"


class Equipment(models.Model):
    equipment_id = models.AutoField(primary_key=True, default=None)
    subcategory = models.ForeignKey(
        Subcategory, on_delete=models.CASCADE, related_name="subcategory_eq", verbose_name="subcategory_id")
    created_at = models.DateTimeField(auto_now_add=True)
    last_modified = models.DateTimeField(auto_now=True)

    def __str__(self):
        return str(self.equipment_id)

    class Meta:
        db_table = "equipment"


class Attribute(models.Model):
    attribute_id = models.AutoField(primary_key=True, default=None)
    attribute_name = models.CharField(max_length=15, unique=True)
    subcategory = models.ManyToManyField(
        Subcategory, through="SubcategoryAttributeMap")
    created_at = models.DateTimeField(auto_now_add=True)
    last_modified = models.DateTimeField(auto_now=True)

    def __str__(self):
        return str(self.attribute_id)+","+self.attribute_name

    class Meta:
        db_table = "attribute"


class SubcategoryAttributeMap(models.Model):
    id = models.AutoField(primary_key=True, default=None)
    subcategory = models.ForeignKey(
        Subcategory, on_delete=models.CASCADE, related_name="subcategory_sub_attr_map", verbose_name="subcategory_id")
    attribute = models.ForeignKey(
        Attribute, on_delete=models.CASCADE, related_name="attribute_sub_attr_map", verbose_name="attribute_id")
    created_at = models.DateTimeField(auto_now_add=True)
    last_modified = models.DateTimeField(auto_now=True)

    def __str__(self):
        return str(self.id)

    class Meta:
        db_table = "subcategory_attribute_map"


class EquipmentDetail(models.Model):
    equipment_detail_id = models.AutoField(primary_key=True, default=None)
    equipment = models.ForeignKey(
        Equipment, on_delete=models.CASCADE, related_name="equipment_eqdetail", verbose_name="equipment_id")
    attribute = models.ForeignKey(
        Attribute, on_delete=models.CASCADE, related_name="attribute_eqdetail", verbose_name="attribute_id")
    value = models.CharField(max_length=15)
    created_at = models.DateTimeField(auto_now_add=True)
    last_modified = models.DateTimeField(auto_now=True)

    def __str__(self):
        return str(self.equipment_detail_id)+","+self.value

    class Meta:
        db_table = "equipment_detail"

期望的输出:

[ 
   { 
      'equipment_id':1,
      'subcategory__name':'laptop',
      'attribute_detail':[ 
         { 
            'attribute_name':'color',
            'attribute_value':'red'
         },
         { 
            'attribute_name':'ram',
            'attribute_value':'6gb'
         }
      ]
   },
   {   'equipment_id':2,
      'subcategory__name':'Mouse',
      'attribute_detail':[ 
         { 
            'attribute_name':'color',
            'attribute_value':'red'
         },
         { 
            'attribute_name':'dpi',
            'attribute_value':'800'
         }
      ]
    }

]

【问题讨论】:

  • 这个(以及 FWIW 的许多其他有用功能)是 fully documented。我可以建议您阅读文档的这一部分吗?这将为您节省大量时间。
  • @brunodesthuilliers 我已经阅读了这一切仍然无法解决这个问题

标签: mysql django django-models django-queryset django-orm


【解决方案1】:

试试这个:

equipments= Equipment.objects.select_related('subcategory').filter(subcategory__category_id=1).prefetch_related(Prefetch('equipment_eqdetail', EquipmentDetail.objects.select_related('attribute')))
results = []
for equipment in equipments:
    temp = {
    'equipment_id': equipment.id,
    'subcategory__name': equipment.subcategory.name,
    }
    attributes = []
    for eq_detail in equipment.equipment_eqdetail.all():
        attributes.append({'attribute_name': eq_detail.attribute.attribute_name, 'attribute_value': eq_detail.value})

    temp['attribute_detail'] = attributes
    results.append(temp)

此查找将有 2 个 sql 查询,这将返回您所需格式的数据。

【讨论】:

  • 这也是获取所有相关设备,但我还需要在获取设备查询集后如何获得这样的输出>equipments=[ [eq_id_1,subcategory_name,eq_attributes_name and respective value] [eq_id_2,subcategory_name,eq_attributes_name and respective value] [eq_id_3,subcategory_name,eq_attributes_name and respective value] ]
  • 请解释您的代码并更新您的答案
  • 所以你也想要 Subcategory 对象?此查询将获取与特定 Equipment 对象相关的所有 EquipmentDetail 对象(具有与 EquipmentDetail 对象相关的属性对象)的所有设备。
  • 我想要 category_id =1 设备的所有相关详细信息,从您的查询中可以说我正在获取查询集,但如何在其上运行循环以获取我上面提到的列表。 @NalinDobhal。
  • @NaveenJain 我已经编辑了我的答案,请立即查看。
【解决方案2】:

我得到了答案。

equipments = Equipment.objects.filter(subcategory__category__category_id=1)  


all_equipments_data = []  

# iterate over each equipment  

for equipment in equipments:
    single_equipment_data = {}  
    single_equipment_data['equipment_id'] = equipment.equipment_id
    single_equipment_data['subcategory__name'] = equipment.subcategory.subcategory_name  

    attributes_detail_of_equipment = []  

# iterate over each equipmentdetail of single equipment
    for eqdetail in equipment.equipment_eqdetail.all(): 

       attributes_detail_of_equipment.append({'attribute_name':eqdetail.attribute.attribute_name,'attribute_value':eqdetail.value})  

       single_equipment_data['attribute_detail'] = attributes_detail_of_equipment  

all_equipments_data.append(single_equipment_data)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-05-26
    • 1970-01-01
    • 1970-01-01
    • 2011-01-15
    • 2021-05-02
    • 2014-05-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多