Django模型嵌套序列化器

时间:2017-08-03 13:01:42

标签: django python-2.7 django-serializer

我有如下的模型结构

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 个答案:

答案 0 :(得分:1)

尝试使用django rest framework

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)

答案 1 :(得分:1)

将模型更改为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)

希望这应该以您要求的格式生成JSON数据。