from rest_framework import serializers from .models import ( Tag, Ingredient, PantryItem, MetaRecipe, Slot, SlotOption, MetaRecipeBase, Recipe, RecipeIngredient, CookLog, ShoppingListItem, ) class TagSerializer(serializers.ModelSerializer): class Meta: model = Tag fields = "__all__" class IngredientSerializer(serializers.ModelSerializer): tags = TagSerializer(many=True, read_only=True) tag_ids = serializers.PrimaryKeyRelatedField( queryset=Tag.objects.all(), many=True, write_only=True, source="tags", required=False ) class Meta: model = Ingredient fields = "__all__" # preferences field included via __all__ class PantryItemSerializer(serializers.ModelSerializer): ingredient_name = serializers.CharField(source="ingredient.name", read_only=True) class Meta: model = PantryItem fields = "__all__" # --- Meta-Recipe nested serializers --- class SlotOptionSerializer(serializers.ModelSerializer): ingredient_name = serializers.CharField(source="ingredient.name", read_only=True) class Meta: model = SlotOption fields = "__all__" class SlotSerializer(serializers.ModelSerializer): options = SlotOptionSerializer(many=True, read_only=True) class Meta: model = Slot fields = "__all__" class MetaRecipeBaseSerializer(serializers.ModelSerializer): ingredient_name = serializers.CharField(source="ingredient.name", read_only=True) class Meta: model = MetaRecipeBase fields = "__all__" class MetaRecipeSerializer(serializers.ModelSerializer): slots = SlotSerializer(many=True, read_only=True) base_ingredients = MetaRecipeBaseSerializer(many=True, read_only=True) class Meta: model = MetaRecipe fields = "__all__" # --- Writable nested meta-recipe --- class SlotOptionWriteSerializer(serializers.Serializer): ingredient_name = serializers.CharField() ingredient_id = serializers.IntegerField(required=False) quantity_per_serving = serializers.DecimalField(max_digits=8, decimal_places=2) unit = serializers.CharField() notes = serializers.CharField(required=False, default="", allow_blank=True) # For auto-creating ingredients default_unit = serializers.CharField(required=False) tags = serializers.ListField(child=serializers.CharField(), required=False, default=list) shelf_life_days = serializers.IntegerField(required=False, allow_null=True, default=None) class SlotWriteSerializer(serializers.Serializer): name = serializers.CharField() required = serializers.BooleanField(default=True) max_choices = serializers.IntegerField(default=1) options = SlotOptionWriteSerializer(many=True) class BaseIngredientWriteSerializer(serializers.Serializer): ingredient_name = serializers.CharField() ingredient_id = serializers.IntegerField(required=False) quantity_per_serving = serializers.DecimalField(max_digits=8, decimal_places=2) unit = serializers.CharField() class MetaRecipeWriteSerializer(serializers.Serializer): name = serializers.CharField() method = serializers.CharField() prep_time_mins = serializers.IntegerField(required=False, allow_null=True, default=None) cook_time_mins = serializers.IntegerField(required=False, allow_null=True, default=None) default_servings = serializers.IntegerField(default=2) gear_needed = serializers.CharField(required=False, default="", allow_blank=True) tags = serializers.ListField(child=serializers.CharField(), required=False, default=list) slots = SlotWriteSerializer(many=True, required=False, default=list) base_ingredients = BaseIngredientWriteSerializer(many=True, required=False, default=list) # --- Fixed Recipe nested serializers --- class RecipeIngredientSerializer(serializers.ModelSerializer): ingredient_name = serializers.CharField(source="ingredient.name", read_only=True) class Meta: model = RecipeIngredient fields = "__all__" class RecipeSerializer(serializers.ModelSerializer): ingredients = RecipeIngredientSerializer(many=True, read_only=True) class Meta: model = Recipe fields = "__all__" # --- Cook Log & Shopping --- class CookLogSerializer(serializers.ModelSerializer): meta_recipe_name = serializers.CharField(source="meta_recipe.name", read_only=True, default=None) recipe_name = serializers.CharField(source="recipe.name", read_only=True, default=None) class Meta: model = CookLog fields = "__all__" class ShoppingListItemSerializer(serializers.ModelSerializer): ingredient_name = serializers.CharField(source="ingredient.name", read_only=True, default=None) class Meta: model = ShoppingListItem fields = "__all__"