Как построить вложенный QuerySet с помощью django ORM?

Как построить формат JSON, который я ожидаю, используя только QuerySet?

Используйте Prefetch или Subquery?

Можете ли вы дать решение, используя только QuerySet?

Это просто демонстрация, я не хочу менять другой код.

Я не хочу использовать JSONField.

Может ли кто-нибудь написать комплекс QuerySet для этого?

Что за дурацкая проверка редактора? Он всегда подсказывает: It looks like your post is mostly code; please add some more details.

модели:

class Product(models.Model):
    name = models.CharField(max_length=128, )
    product_attr = models.ManyToManyField("ProductAttr", through="ProductBindAttr", )


class ProductAttr(models.Model):
    attr_name = models.CharField(max_length=128, unique=True, )


class ProductBindAttr(models.Model):
    class Meta:
        UniqueConstraint("product", "attr_key", "attr_value", name='unique_bind_attr')

    product = models.ForeignKey("Product", on_delete=models.CASCADE, )
    attr_key = models.ForeignKey("ProductAttr", on_delete=models.CASCADE, )
    attr_value = models.CharField(max_length=128, )

сериализаторы:

class ProductBindAttrNestedSerializer(serializers.ModelSerializer):
    class Meta:
        model = ProductBindAttr
        fields = ('attr_value', 'product')

    product = serializers.StringRelatedField()


class ProductGroupByBindAttrSerializer(serializers.ModelSerializer):
    class Meta:
        model = ProductAttr
        fields = ("attr_name", "attr_values")

    attr_values = ProductBindAttrNestedSerializer(many=True, source="productbindattr_set")

просмотров:

class ProductGroupByBindAttrViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
    queryset = ProductAttr.objects.all()

    # how can I just change `queryset` to do that?

    serializer_class = ProductGroupByBindAttrSerializer

json:

    {
        "attr_name": "Height",
        "attr_values": [
            {
                "attr_value": "13 cm",
                "products": {
                    "name": "G304"
                }
            },
            {
                "attr_value": "13 cm",
                "products": {
                    "name": "G305"
                }
            },
            {
                "attr_value": "14 cm",
                "products": {
                    "name": "G306"
                }
            }
        ]
    }

Результат, который я ожидаю:

    {
        "attr_name": "Height",
        "attr_values": [
            {
                "attr_value": "13 cm",
                "products": {
                    "name": "G304",
                    "name": "G305", // I want to merge products which same `attr_value`
                }
            },
            {
                "attr_value": "14 cm",
                "products": {
                    "name": "G306"
                }
            }
        ]
    }
Вернуться на верх