我需要显示与同一模型有多对多关系的相关字段。 Django Rest 框架工作
I need to show related fileds which have many to many relation with same model. Django Rest Frame work
我正在尝试创建一个相关的产品字段,我已将其添加到具有多对多关系的模型中,并将其设置为自我,因为我将手动 select 相关产品。
class ProductsSerializer(serializers.ModelSerializer):
images = ImagesSerializer(many=True)
color = ColorSerializer(many=False)
class Meta:
fields = (
'url',
'id',
"code",
"sku",
"title",
"slug",
"state",
"old_price",
"price",
"valid",
"in_stock",
"category",
"related_products",
"color",
"images",
"video",
"description",
"fabric",
"model_size_info",
)
model = Products
我无法引用同一个序列化程序,我需要在 api json 中获取产品详细信息。我找不到这样做的方法。
提前感谢大家的帮助。
Method-1: 覆盖 __init__()
方法
class ProductsSerializer_Temp(serializers.ModelSerializer):
images = ImagesSerializer(many=True)
class Meta:
fields = (
'url',
'id',
"title",
"images",
)
model = Products
class ProductsSerializer(ProductsSerializer_Temp):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields.update(
{"related_products": ProductsSerializer_Temp()}
)
首先,我认为你应该使用类似DynamicFieldsModelSerializer的东西来防止递归
class DynamicFieldsModelSerializer(serializers.ModelSerializer):
"""
A ModelSerializer that takes an additional `fields` argument that
controls which fields should be displayed.
"""
def __init__(self, *args, **kwargs):
# Don't pass the 'fields' arg up to the superclass
fields = kwargs.pop('fields', None)
# Instantiate the superclass normally
super(DynamicFieldsModelSerializer, self).__init__(*args, **kwargs)
if fields is not None:
# Drop any fields that are not specified in the `fields` argument.
allowed = set(fields)
existing = set(self.fields)
for field_name in existing - allowed:
self.fields.pop(field_name)
那么,您可以使用SerializerMethodField
并在相关产品中指定您想要的字段('不要传递related_products
以防止递归'):
class ProductsSerializer(DynamicFieldsModelSerializer):
images = ImagesSerializer(many=True)
related_products = serializers.SerializerMethodField()
def get_related_products(self, obj):
return ProductsSerializer(obj.related_products, many=True, fields=('url', 'id', "title", "images")).data
class Meta:
fields = (
'url',
'id',
"title",
"related_products",
"images",
)
model = Products
这是我遇到的解决方案。
我创建了另一个 Serializer
class ProductsSerializerTemp(serializers.ModelSerializer):
color = ColorSerializer(many=False)
class Meta:
fields = (
"color",
"url"
)
model = Products
然后我将它引用到我原来的序列化器
class ProductsSerializer(serializers.ModelSerializer):
images = ImagesSerializer(many=True)
color = ColorSerializer(many=False)
related_products = ProductsSerializerTemp(many=True)
class Meta:
fields = (
'url',
'id',
"code",
"sku",
"title",
"slug",
"state",
"old_price",
"price",
"valid",
"in_stock",
"category",
"related_products",
"color",
"images",
"video",
"description",
"fabric",
"model_size_info",
)
model = Products
我几乎完成了这项工作,我不确定这是否是最佳解决方案,但效果很好。
我正在尝试创建一个相关的产品字段,我已将其添加到具有多对多关系的模型中,并将其设置为自我,因为我将手动 select 相关产品。
class ProductsSerializer(serializers.ModelSerializer):
images = ImagesSerializer(many=True)
color = ColorSerializer(many=False)
class Meta:
fields = (
'url',
'id',
"code",
"sku",
"title",
"slug",
"state",
"old_price",
"price",
"valid",
"in_stock",
"category",
"related_products",
"color",
"images",
"video",
"description",
"fabric",
"model_size_info",
)
model = Products
我无法引用同一个序列化程序,我需要在 api json 中获取产品详细信息。我找不到这样做的方法。
提前感谢大家的帮助。
Method-1: 覆盖 __init__()
方法
class ProductsSerializer_Temp(serializers.ModelSerializer):
images = ImagesSerializer(many=True)
class Meta:
fields = (
'url',
'id',
"title",
"images",
)
model = Products
class ProductsSerializer(ProductsSerializer_Temp):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields.update(
{"related_products": ProductsSerializer_Temp()}
)
首先,我认为你应该使用类似DynamicFieldsModelSerializer的东西来防止递归
class DynamicFieldsModelSerializer(serializers.ModelSerializer):
"""
A ModelSerializer that takes an additional `fields` argument that
controls which fields should be displayed.
"""
def __init__(self, *args, **kwargs):
# Don't pass the 'fields' arg up to the superclass
fields = kwargs.pop('fields', None)
# Instantiate the superclass normally
super(DynamicFieldsModelSerializer, self).__init__(*args, **kwargs)
if fields is not None:
# Drop any fields that are not specified in the `fields` argument.
allowed = set(fields)
existing = set(self.fields)
for field_name in existing - allowed:
self.fields.pop(field_name)
那么,您可以使用SerializerMethodField
并在相关产品中指定您想要的字段('不要传递related_products
以防止递归'):
class ProductsSerializer(DynamicFieldsModelSerializer):
images = ImagesSerializer(many=True)
related_products = serializers.SerializerMethodField()
def get_related_products(self, obj):
return ProductsSerializer(obj.related_products, many=True, fields=('url', 'id', "title", "images")).data
class Meta:
fields = (
'url',
'id',
"title",
"related_products",
"images",
)
model = Products
这是我遇到的解决方案。 我创建了另一个 Serializer
class ProductsSerializerTemp(serializers.ModelSerializer):
color = ColorSerializer(many=False)
class Meta:
fields = (
"color",
"url"
)
model = Products
然后我将它引用到我原来的序列化器
class ProductsSerializer(serializers.ModelSerializer):
images = ImagesSerializer(many=True)
color = ColorSerializer(many=False)
related_products = ProductsSerializerTemp(many=True)
class Meta:
fields = (
'url',
'id',
"code",
"sku",
"title",
"slug",
"state",
"old_price",
"price",
"valid",
"in_stock",
"category",
"related_products",
"color",
"images",
"video",
"description",
"fabric",
"model_size_info",
)
model = Products
我几乎完成了这项工作,我不确定这是否是最佳解决方案,但效果很好。