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)
Вернуться на верх