qwertp
qwertp

Reputation: 859

AttributeError when attempting to get a value for field on serializer

Trying to get a manytomany relationship in django but I'm getting the following error -

Got AttributeError when attempting to get a value for field name on serializer GenreSerializer. The serializer field might be named incorrectly and not match any attribute or key on the Movie instance. Original exception text was: 'Movie' object has no attribute 'name'.

There is a similar answer here recommending setting many=True, but it doesn't work - Attribute error when attempting to get a value for field

models.py

class Genre(models.Model):
  name = models.CharField(max_length=255,unique=True)

  def __unicode__(self):
    return self.name

class Movie(models.Model):
  mname = models.CharField(max_length=255)
  genres = models.ManyToManyField(Genre,related_name='movies')

  def __unicode__(self):
    return self.mname

serializers.py

class GenreSerializer(serializers.ModelSerializer):
  class Meta:
    model = Genre
    fields = ('name','id')

class MovieSerializer(serializers.ModelSerializer):
  genres = GenreSerializer(many=True, read_only=True)    

  class Meta:
    model = Movie
    fields = ('id','genres','mname')

urls.py

urlpatterns = [
url(r'^genres/$', views.GenreList.as_view()),
url(r'^genres/(?P<pk>[0-9]+)$', views.GenreDetail.as_view()),
]

urlpatterns = format_suffix_patterns(urlpatterns)

views.py

class GenreList(generics.ListCreateAPIView):
  queryset = Genre.objects.all()
  serializer_class = GenreSerializer


class GenreDetail(generics.RetrieveUpdateDestroyAPIView):
  serializer_class = GenreSerializer

  def get_queryset(self):
    genres = Genre.objects.get(pk=self.kwargs.get('pk', None))
    movies = Movie.objects.filter(genres=genres)
    return movies

Upvotes: 5

Views: 18930

Answers (3)

Ghouse Shaik
Ghouse Shaik

Reputation: 11

Let just take a simple example model in which you have three fields

from django.db import models

class Movie(models):
  name = models.CharField()
  description = models.TextField()
  created = models.DateTimeField(auto_now_add=True)

If you're using this in serializer field then you have to pass argument "many=true" along with model name for example

movie = Movie.objects.all()
serializer = MovieSerializer(movie, many=True)

this is caused because when you have more than one objects(fields) in your model and you want to loop through every field for that we use "many=True"

Upvotes: 1

Dubey Ravi vinod
Dubey Ravi vinod

Reputation: 338

If yout are using a function based serializer, and wanted to fetch all the information of the ModelSerializer. Then use many=True

@api_view()
def movie_list(request):

    movies = Movie.objects.all()
    serializer = MovieSerializer(movies)
    print(serializer)
    return Response(serializer.data)

For the above code, the response was

Got AttributeError when attempting to get a value for field name on serializer MovieSerializer. The serializer field might be named incorrectly and not match any attribute or key on the QuerySet instance. Original exception text was: 'QuerySet' object has no attribute 'name'.

If we just add many=True in serializer = MovieSerializer(movies, many=True)`:

@api_view()
def movie_list(request):

    movies = Movie.objects.all()
    serializer = MovieSerializer(movies, many=True)
    print(serializer)
    return Response(serializer.data)

Then the output we get is please replace this obnoxious image with text

Upvotes: 15

Similar to your other question, you are using the incorrect serializer on your GenreDetail view. You need to add the serializer for the type of models you are returning from get_queryset:

class GenreDetail(generics.RetrieveUpdateDestroyAPIView):
    serializer_class = MovieSerializer

    def get_queryset(self):
        genres = Genre.objects.get(pk=self.kwargs.get('pk', None))
        movies = Movie.objects.filter(genres=genres)
        return movies

Upvotes: 7

Related Questions