Got AttributeError when attempting to get a value for field `people` on serializer `commentsSerializer`

Viewed 35

I am building a blog website and I am using Django rest framework I want to fetch top 2 comments for a particular post along with their related data such as user details.

Now I have user details in two models

  1. User
  2. People

and the comments model is related to the user model using foreign key relationship

Models ->

  1. Comments

     class Comment(models.Model):
         comment = models.TextField(null=True)
         Created_date = models.DateTimeField(auto_now_add=True)
         Updated_date = models.DateTimeField(auto_now=True)
         post = models.ForeignKey(Post, on_delete=models.CASCADE, 
             related_name='comments_post')
         user = models.ForeignKey(User, on_delete=models.CASCADE, 
             related_name='comments_user')
    

The People model is also connected to the user model with a foreign key relationship

People Model ->

class People(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE,related_name='people')
    Name = models.CharField(max_length=255,null=True)
    following = models.ManyToManyField(to=User, related_name='following', blank=True)
    photo = models.ImageField(upload_to='profile_pics', blank=True,null=True)
    Phone_number = models.CharField(max_length=255,null=True,blank=True)
    Birth_Date = models.DateField(null=True,blank=True)
    Created_date = models.DateTimeField(auto_now_add=True)
    Updated_date = models.DateTimeField(auto_now=True)

for fetching the comments I am using rest-framework and the serializers look like this

class UserSerializer(serializers.Serializer):
    username = serializers.CharField(max_length=255)

class peopleSerializer(serializers.Serializer):
    Name = serializers.CharField(max_length=255)

class commentsSerializer(serializers.Serializer):
    id = serializers.IntegerField(read_only=True)
    comment = serializers.CharField(max_length=255)
    Created_date = serializers.DateTimeField()
    user = UserSerializer()
    people = peopleSerializer()

The query to fetch the comments look like this ->

post_id = request.GET.get('post_id')
        comments = Comment.objects.filter(post_id=post_id).select_related('user').prefetch_related('user__people').order_by('-Created_date')[:2]
        serializer = commentsSerializer(comments, many=True)
        return Response(serializer.data)

I am getting this error ->

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

Unable to find a way out.

1 Answers

The source is user.people, not people, so:

class commentsSerializer(serializers.Serializer):
    # …
    people = peopleSerializer(source='user.people')

In the .select_related(…) [Django-doc] to can specify user__people: this will imply selecting user and will fetch the data in the same query, not in an extra query as is the case for .prefetch_related(…) [Django-doc]:

post_id = request.GET.get('post_id')
comments = Comment.objects.filter(
    post_id=post_id
).select_related('user__people').order_by('-Created_date')[:2]
serializer = commentsSerializer(comments, many=True)
return Response(serializer.data)

Note: normally a Django model is given a singular name, so Person instead of People.


Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the User model [Django-doc] directly. For more information you can see the referencing the User model section of the documentation.


Note: normally the name of the fields in a Django model are written in snake_case, not PascalCase, so it should be: created_date instead of Created_date.

Related