代码之家  ›  专栏  ›  技术社区  ›  Karesh A

Django模型嵌套序列化程序

  •  0
  • Karesh A  · 技术社区  · 7 年前

    我的模型结构如下

    class BaseProduct:
       id = models.CharField(max_length=15)
       name = models.CharField(max_length=20)
    
    class Product
       base_product = ForeigKey(BaseProduct)
       name = models.CharField(max_length=20)
    
    class Condition:
       category = models.ForeignKey(Product, related_name='allowed_product')
       check = models.IntegerField(default=0)
       allow = models.PositiveSmallIntegerField(default=1)
    

    Product.objects.filter(condition__allow=1, condition__check=1)
    

    我想要如下格式 基于允许和检查筛选器

    [
        {
            "name": "BaseProduct 1",
            "products": [
                {
    
                    "name": "TV",
    
                }, {}, ....
    
            ]
        },
    ........
    ]
    
    2 回复  |  直到 7 年前
        1
  •  1
  •   Brown Bear    7 年前

    如果您使用django rest框架,请尝试一下

    from rest_framework import serializers
    from rest_framework.fields import empty
    from django.utils.functional import cached_property
    
    
    class ProductSerializer(serializers.ModelSerializer):
    
        class Meta:
            model = Product
            fields = ('name')
    
    
    class BaseProductSerializer(serializers.ModelSerializer):
            products = serializers.SerializerMethodField()
    
        class Meta:
            model = BaseProduct
            fields = ('name', 'products')
    
        def __init__(self, instance=None, data=empty, **kwargs):
            self._condition_allow = kwargs.pop('condition_allow', 1)
            super(BaseProductSerializer, self).__init__(instance=None, data=empty, **kwargs)
    
        @cached_property
        def _request_data(self):
            request = self.context.get('request')
            # if POST
            # return request.data if request else {}
            # if GET params
            return request.query_params if request else {}
    
        @cached_property
        def _condition(self):
             return self._request_data.get('CONDITION_PARAM_NAME')
    
        def get_products(self, obj):
            qs = obj.product_set.filter(condition__allow=self._condition_allow, condition__check=1)
            serializer = ProductSerializer(qs, many=True)
            #                             ^^^^^
            return serializer.data
    

    在视图中

    serialiser(qs, condition_allow=5)
    
        2
  •  1
  •   Kakar    7 年前

    related_name 对于具有反向关系的外键:

    class BaseProduct:
       id = models.CharField(max_length=15)
       name = models.CharField(max_length=20)
    
    class Product
       base_product = ForeigKey(BaseProduct, related_name='products')
       name = models.CharField(max_length=20)
    
    class Condition:
       category = models.ForeignKey(Product, related_name='conditions')
       check = models.IntegerField(default=0)
       allow = models.PositiveSmallIntegerField(default=1)
    

    class BaseProductSerializer:
       class Meta:
        model = BaseProduct
        fields = ('name', 'products',)
    
    class ProductSerializer:
       class Meta:
        model = Product
        fields = ('conditions',)
    
    class ConditionSerializer:
       class Meta:
        model = Condition
        fields = '__all__'
    

    最后,在您的视图中,更改以下内容:

    Product.objects.filter(condition__allow=1, condition__check=1)
    

    BaseProduct.objects.filter(products__conditions__allow=1, products__conditions__allow=1)