Django многие к многим кверинг
Я создаю сайт электронной коммерции, используя Django, мои модели выглядят следующим образом :
class ProductAttribute(models.Model):
product=models.ForeignKey(Product,on_delete=models.CASCADE)
attributes_values = models.ManyToManyField(AttributeValue,verbose_name="Liste des attributs")
stock = models.PositiveIntegerField()
price = models.PositiveIntegerField(verbose_name="Prix")
image = models.ImageField(blank=True,null=True,upload_to="products")
class AttributeValue(models.Model):
attribute=models.ForeignKey(Attribute,on_delete=models.CASCADE,verbose_name="Attribut")
value = models.CharField(max_length=50,verbose_name="Valeur")
class Attribute(models.Model):
name = models.CharField(max_length=50,verbose_name="Nom")
my view.py
def getatts(request,product_id):
products_with_attributes=ProductAttribute.objects.filter(product__id=product_id)
res=#..... missing code to get attributes with values
return res
В front end я хочу получить атрибуты конкретного товара, чтобы получить их по порядку, использовать их в select (например, размер, выбор цвета), например, если набор запросов ProductAttribute
имеет вид:
[{id:1,product:1,attributes_values:[3,4],...},{id:1,product:1,attributes_values:[5,6],...}]
результат в JSON
будет выглядеть так:
{
result:[
{
key: "color", // attribute.name
values: [
{id: 1, value: "Red",
choices:{
key:"size", // second attribute.name
values:[{id:3,value:"L"},{id:4,value:"XL"}]
}
},
{id: 2, value: "Black",
choices:{
key:"size",
values:[{id:5,value:"M"},{id:6,value:"XXL"}]
}
},
]
}
]
}
Примечание: Я использую MYSQL
в качестве базы данных
это грязный способ сделать это и это статический способ (максимум два значения атрибута) есть ли способ сделать это используя Django ORM:
products=ProductAttribute.objects.filter(product__id=id)
res={}
keys=[]
values=[]
for attribute_value in products.first().attributes_values.all():
keys.append({"id":attribute_value.attribute.id,"name":attribute_value.attribute.name})
res["id"]=keys[0]["id"]
res["name"]=keys[0]["name"]
# print(res)
for p in products:
attributes_values=p.attributes_values.all()
# print([ { "id":attv.id,"value":attv.value, "attribute_id":attv.attribute.id, "attribute_name":attv.attribute.name } for attv in attributes_values ])
for attv in attributes_values:
if attv.attribute.id==res["id"]:
exists=False
for v in values:
if v["id"]==attv.id:
exists=True
if not exists:
if len(keys)>1:
first_attribute={ "id":attv.id,"value":attv.value}
first_attribute["sub"]={"id":keys[1]["id"],"name":keys[1]["name"],"values":[]}
for pp in products:
for attv2 in pp.attributes_values.filter(productattribute__id__in= products.filter(attributes_values__id=attv.id).values("id")):
if attv2.attribute.id!=res["id"]:
exists2=False
for sub_value in first_attribute["sub"]["values"]:
if sub_value["id"]==attv2.id:
exists2=True
if not exists2:
first_attribute["sub"]["values"].append({"id":attv2.id,"value":attv2.value})
# first_attribute["sub"]["values"]
# p.attributes_values.all()[1]
values.append(first_attribute)
else:
values.append({ "id":attv.id,"value":attv.value,"sub":{}})
print(attv.attribute.id)
res["values"]=values
print(res)