使用 Django ORM 查询获取模型对象的所有相关详细信息?
get all the related detail of a a model object by using django ORM queries?
这些是我的 Django 模型。
数据库模型说明:
thinkpad 是 laptop subcategory
的 equipment
,laptop 子类别 有一个 category
叫做 electronics.
现在 laptop 可以有很多 attributes
像 processor,ram,color,screen_size
。
问题:
找出所有 equipment
和 equipment detail ,subcategory_name and attribute names,value
的 category_id =1 。
型号:
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'
}
]
}
]
试试这个:
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 查询,这将 return 数据以您想要的格式显示。
我得到了这个答案。
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)
这些是我的 Django 模型。
数据库模型说明:
thinkpad 是 laptop subcategory
的 equipment
,laptop 子类别 有一个 category
叫做 electronics.
现在 laptop 可以有很多 attributes
像 processor,ram,color,screen_size
。
问题:
找出所有 equipment
和 equipment detail ,subcategory_name and attribute names,value
的 category_id =1 。
型号:
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'
}
]
}
]
试试这个:
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 查询,这将 return 数据以您想要的格式显示。
我得到了这个答案。
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)