He anidado serializador (AmountSerializer). Necesito un campo meal_name en un ViewSet. Pero cuando este campo está anidado, no necesito que se vea en el punto final (en MealSerializer). ¿Cómo excluir el campo del serializador anidado cuando en realidad está anidado? modelos.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_nameserializadores.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')Prefiero usar un truco para excluir algunos de los campos que no son necesarios en ciertas situaciones. Puede heredar su serializador de ExcludeFieldsModelSerializer y excluir los campos que desee para que el serializador no serialice ese campo.
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')