Django 模型嵌套序列化器
Django model nested 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",
}, {}, ....
]
},
........
]
尝试一下,如果你使用 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)
更改您的模型,使外键具有 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 数据。
我有如下模型结构
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 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)
更改您的模型,使外键具有 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 数据。