How to serialize using django rest_framework a Man

2019-04-07 13:47发布

问题:

I have a Recipe model that holds an M2M field of an IngredientType object. This field, aka ingredient_list, uses the notorious 'through' model via an Ingredient object that adds extra data to my IngredientType. these are my classes:

class Recipe(models.Model):
    user_profile = models.ForeignKey(UserProfile, null=True, blank = True)
    name = models.CharField(max_length=200)
    photo1 = models.ImageField( upload_to = 'images/recipies', help_text="This photo will show by default")
    ingredient_list = models.ManyToManyField(IngredientType,through='Ingredient')

class Ingredient(models.Model):
    ingredient_type = models.ForeignKey(IngredientType)
    recipe = models.ForeignKey(Recipe)
    amount = models.IntegerField()
    units = models.CharField(max_length=4,choices=UNIT, 
                               default=None, null=True, blank = True)

class IngredientType(models.Model):
    name = models.CharField(max_length=200)
    plural_name = models.CharField(max_length=200)
    photo = models.ImageField( upload_to = 'images/ingredients')
    is_main = models.BooleanField()

i've tried serializing them using the rest_framework:

class IngredientTypeSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = IngredientType
        fields=('name', 'plural_name', 'photo', 'is_main')

class IngredientSerializer(serializers.HyperlinkedModelSerializer):
    ingredient_type = IngredientTypeSerializer(source = 'ingredient_type')
    amount =  serializers.Field(source='ingredient_type.amount')
    units =  serializers.Field(source='ingredient_type.units')
    recipe = serializers.Field(source='Recipe.name')
class Meta:
    model = Ingredient
    fields=('amount', 'units')

class RecipeSerializer(serializers.ModelSerializer):
    ingredient_list = IngredientSerializer(source='ingredient_list', many=True, read_only = True)
    class Meta:
        model = Recipe
        fields = ('user_profile', 'name','photo1','ingredient_list')

but when trying to run this, I get an AttributeError : 'IngredientType' object has no attribute 'ingredient_type'

clearly, when I change the line:

ingredient_list = IngredientSerializer(source='ingredient_list', many=True, read_only = True)

to:

ingredient_list = IngredientTypeSerializer(source='ingredient_list', many=True, read_only = True)

that is, change the Serializer, it works, but without fetching me the Ingredient data. i've used this link: Include intermediary (through model) in responses in Django Rest Framework as reference, but obviously it hasn't solved my problems.
Any help would be appreciated. tnx, Nitzan

回答1:

On your Recipe model, for the ingredient_list field you have a ManyToManyField pointing to IngredientType.

On your RecipeSerializer the ingredient_list field is not using the IngredientTypeSerializer but rather the IngredientSerializer.

This is the error. (And it explains the error message — the actual model at the source doesn't have the attribute being looked for by the serializer.)

Beyond this, your naming scheme is massively confusing. "Recipe" is fine, but what you're calling "IngredientType" should probably just be "Ingredient" and then you should find a distinct name for the through table. (Maybe "RecipeIngredientDetails")

I hope that helps.