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
Creating and Using Serializers To create a basic serializer one needs to import serializers class from rest_framework and define fields for a serializer just like creating a form or model in Django.
To serialize many to many field with Python Django rest framework, we can add a serializer with many set to True . to create the PostSerializer with the tag field assigned to the TagSerializer instance. We set many to true to let us serialize many to many fields.
Serializers allow complex data such as querysets and model instances to be converted to native Python datatypes that can then be easily rendered into JSON , XML or other content types.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With