python - 如何处理 Django Rest Framework 中的嵌套序列化器字段?
问题描述
我有嵌套的序列化器(AmountSerializer)。我需要一个 ViewSet 中的一个字段meal_name。但是当这个字段被嵌套时,我不需要在端点(在 MealSerializer 中)看到它。实际嵌套时如何从嵌套序列化程序中排除字段?模型.py:
class MealType(models.Model):
name = models.TextField()
def __str__(self):
return self.name
class Ingredient(models.Model):
name = models.TextField()
def __str__(self):
return self.name
class Meal(models.Model):
name = models.TextField()
type = models.ForeignKey(MealType, on_delete=models.CASCADE, default=None)
recipe = models.TextField()
photo = models.ImageField(null=True, height_field=None, width_field=None, max_length=None,upload_to='media/')
ingredients = models.ManyToManyField(Ingredient)
def __str__(self):
return self.name
class IngredientAmount(models.Model):
ingredient_name = models.ForeignKey(Ingredient, on_delete=models.CASCADE, default=None)
amount = models.FloatField(default=None)
meal = models.ForeignKey(Meal, on_delete=models.CASCADE, default=None, related_name='meal_id')
class Meta:
ordering = ['meal']
def __str__(self):
return self.ingredient_name
序列化程序.py:
class AmountSerializer(serializers.ModelSerializer):
ingredient_name= serializers.ReadOnlyField(source='ingredient_name.name')
-->#meal_name = serializers.ReadOnlyField(source='meal.name')
#I CAN'T use ReadOnlyField( #with write_only=True)
#i trired use PrimaryKeyRelatedField
# butgot AssertionError: Relational field must provide a `queryset` argument, override `get_queryset`, or set read_only=`True`.
class Meta:
model = IngredientAmount
fields = ('ingredient_name','amount','meal_name')
class MealSerializer(serializers.ModelSerializer):
type_name= serializers.ReadOnlyField(source='type.name')
ingredients = serializers.SlugRelatedField(read_only=True, slug_field='name', many=True)
amount = AmountSerializer(read_only=True, many=True,source='meal_id')
class Meta:
model = Meal
fields = ('id', 'name', 'type_name', 'recipe', 'photo', 'ingredients','amount')
解决方案
我宁愿使用一种技巧来排除某些在某些情况下不需要的字段。您可以从 继承您的序列化程序ExcludeFieldsModelSerializer
,并排除您想要的任何字段,以便序列化程序不会序列化该字段。
class ExcludeFieldsModelSerializer(serializers.ModelSerializer):
"""
A ModelSerializer that takes an additional `exclude_fields` argument that
controls which fields should be excluded from the serializer.
Plagiarised from https://www.django-rest-framework.org/api-guide/serializers/#dynamically-modifying-fields
"""
def __init__(self, *args, **kwargs):
# Don't pass the 'exclude_fields' arg up to the superclass
exclude_fields = kwargs.pop('exclude_fields', None)
# Instantiate the superclass normally
super(ExcludeFieldsModelSerializer, self).__init__(*args, **kwargs)
if exclude_fields is not None:
# Drop any fields that are specified in the `exclude_fields` argument.
drop = set(exclude_fields)
for field_name in drop:
self.fields.pop(field_name)
class AmountSerializer(ExcludeFieldsModelSerializer):
ingredient_name= serializers.ReadOnlyField(source='ingredient_name.name')
meal_name = serializers.CharField(read_only=True, source='meal.name')
class Meta:
model = IngredientAmount
fields = ('ingredient_name','amount','meal_name')
class MealSerializer(serializers.ModelSerializer):
type_name= serializers.ReadOnlyField(source='type.name')
ingredients = serializers.SlugRelatedField(read_only=True, slug_field='name', many=True)
amount = AmountSerializer(read_only=True, many=True, source='meal_id', exclude_fields={'meal_name'})
class Meta:
model = Meal
fields = ('id', 'name', 'type_name', 'recipe', 'photo', 'ingredients','amount')
推荐阅读
- c++ - 有没有一种递归方式来制作这个字符串数组?
- google-app-engine - 如何使用 Hot Reloading 和其他支持的库在本地测试 Google App Engine 应用程序?
- teechart - 将 teeChart 复制到 ReportBuilder 以进行打印的最佳方法
- python - 不支持的操作 _FusedBatchNormV3 与 tensorRT 和 jetson tx2
- google-cloud-data-fusion - 我们可以使用 jdbc 驱动程序使用数据融合从 mariaDB 和 SAP-HANA 读取
- react-native - React Native 找不到变量 $refresh req$
- python - 在 PYTHON 中将网格从一个进程转移到另一个进程
- .net - 从另一个解决方案添加 dotnet 4.5 项目
- facebook-graph-api - Instagram 图形 API - 见解
- java - 我试着做一个猜谜游戏,让用户决定猜的最大数字是多少