I have a model for recipes and many-to-many model that represents favorite recipes by users:
class Recipe(models.Model):
author = models.ForeignKey(User, on_delete=models.CASCADE)
name = models.CharField(max_length=LENGTH_FOR_TEXTFIELD)
image = models.ImageField()
text = models.TextField(max_length=LENGTH_FOR_TEXTFIELD)
cooking_time = models.PositiveSmallIntegerField()
def __str__(self):
return self.name
class FavoriteRecipe(models.Model):
recipe = models.ForeignKey(Recipe, on_delete=models.CASCADE)
user = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return self.recipe.name
After POST request an entry in that model is created (recipe ID and user ID) and i am trying to write a serializer for response that will contain info about recipe itself:
class FavoriteRecipeSerializerForRead(serializers.ModelSerializer):
class Meta:
model = FavoriteRecipe
fields = ('id', 'name', 'image', 'cooking_time')
So the problem is that i cannot insert into this serializer any recipe-field because i keep getting error:
django.core.exceptions.ImproperlyConfigured: Field name `name` is not valid for model `FavoriteRecipe`
I tried to imply select_related() and .annotate(field=Value(Query)) in my viewset like this but nothing seems to work:
class FavoriteRecipeViewSet(viewsets.ModelViewSet):
queryset = FavoriteRecipe.objects.all()
serializer_class = FavoriteRecipeSerializerForRead
def get_queryset(self):
queryset = FavoriteRecipe.objects.all().annotate(
name=Value(
Recipe.objects.filter(id=self.id).values('cooking_time',)
)
)
return queryset
The question is: how could i do this the proper way?
Why not serialize the Recipe
?
class RecipeSerializer(serializers.ModelSerializer):
class Meta:
model = Recipe
fields = ('id', 'name', 'image', 'cooking_time')
we can use this for Recipe
s that are not a Favorite
one.
In the ViewSet
, we can work with the favorite Recipe
s of a user:
class FavoriteRecipeViewSet(viewsets.ModelViewSet):
queryset = Recipe.objects.all()
serializer_class = RecipeSerializer
def get_queryset(self):
return Recipe.objects.filter(favoriterecipe__user=self.request.user)
You will need to add authentication [drf-doc] to ensure there is a request.user
.