【问题标题】:Django model nested serializerDjango 模型嵌套序列化器
【发布时间】:2017-08-03 13:01:42
【问题描述】:

我有如下模型结构

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",

            }, {}, ....

        ]
    },
........
]

【问题讨论】:

    标签: django python-2.7 django-serializer


    【解决方案1】:

    试试吧,如果你使用 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)
    

    【讨论】:

    • 如何通过序列化器内部的条件检查?视图中的条件__check =1(值 1 这可能会有所不同。)?
    • @RoshanA 使用请求中的示例参数进行编辑,DRF 的所有信息
    • 您好,谢谢。条件参数不是来自请求。我必须根据查询参数处理内部视图并找到 ID。如何直接将该 id 传递给序列化程序以获取数据。
    • @RoshanA 很高兴为您提供帮助,我添加了 init 方法进行编辑,并且新导入,也更改了 get_products
    • 试图访问序列化的.data 表示。你应该先调用.is_valid(),或者访问.initial_data而不是错误?
    【解决方案2】:

    将您的模型更改为具有 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 数据。

    【讨论】:

    • 内部连接的工作方式是错误的。此查询不会给出正确的结果。
    猜你喜欢
    • 2014-07-26
    • 2018-07-05
    • 2019-06-02
    • 2017-11-15
    • 1970-01-01
    • 2017-07-12
    • 2020-04-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多