Home > Net >  Django Rest Framework - Why is serializer.data giving me an empty result set but printing the serial
Django Rest Framework - Why is serializer.data giving me an empty result set but printing the serial

Time:01-31

I have created a view to search posts based on their body text. I added a breakpoint to the view and I tested it with mutliple search terms and it works. The problem I have is when I do a print(serializer) in the console then I see the data of all the posts it found. But doing a print(serializer.data) gives me body:null in the data object in the front end console and an empty dictionary in the back end console.

I am using PostgreSQL

Why am I getting body: null?

Here is the response in the console for print(serializer):

SearchSerializer(<QuerySet [<Post: This is a post>, <Post: This is another post>, <Post: Post THREE>, <Post: Post ONE>, <Post: Post ONE by the user>, <Post: Post TWO by the user>]>):
    body = CharField(allow_blank=True, allow_null=True, label='Content', max_length=5000, required=False, style={'base_template': 'textarea.html'})

Here is the view:

class SearchPosts(APIView):
    permission_classes = [IsAuthenticated]    

    def post(self, request, *args, **kwargs):
        term = request.data.get("term")
        posts = Post.objects.filter(body__search=term)
        serializer = SearchSerializer(posts)
        breakpoint()
        return Response(serializer.data, status=HTTP_200_OK)

Here is the serializer:

class SearchSerializer(serializers.ModelSerializer):

    class Meta:
        model = Post
        fields = [
            'body'
        ]

Here is the post model:

class Post(models.Model):

    body = models.TextField("content", blank=True, null=True, max_length=5000)
    slug = AutoSlugField(populate_from=["category", "created_at"])
    user = models.ForeignKey(
        User, on_delete=models.CASCADE, related_name="posts")
    published = models.BooleanField(default=False)

    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        verbose_name = "post"
        verbose_name_plural = "posts"
        db_table = "posts"
        ordering = ["created_at"]
        get_latest_by = "created_at"

    def __str__(self):
        return self.body[0:30]

    def get_absolute_url(self):
        return self.slug

How am I then supposed to get the data in the front end?

UPDATE

If in the view the request object looks like this:

<rest_framework.request.Request: GET '/api/v1/posts/search/?term=looking'>

Then how do I get the term? ('looking' at the moment)

Because request.data gives me None

kwargs is an empty dictionary

So I changed the view and now it makes even less sense:

class SearchPosts(APIView):
    permission_classes = [IsAuthenticated]    

    def get(self, request, *args, **kwargs):
        term = request.GET.get("term")
        posts = Post.objects.all().filter(body__search=term)
        breakpoint()
        serializer = SearchSerializer(posts)
        
        return Response(serializer.data, status=HTTP_200_OK)

Now I get an empty result if I do a print(posts). The term is correct I checked that so why is body__search not working anymore?

Changed it to a ListAPIView and I still get an empty data array in the response:

# GENERIC VIEW TO GET POSTS FOUND BASED ON A SEARCH TERM
class SearchPosts(generics.ListAPIView):
    permission_classes = [IsAuthenticated]    
    serializer_class = SearchSerializer
    def get_queryset(self):
        term = self.request.GET.get("term")
        return Post.objects.filter(body__search=term)

If I remove the filter then all the posts data is in the response so why is body__search not working?

CodePudding user response:

  def get(self, request, format=None):
        all_objects = Model.objects.all()
        serializer = YourSerializer(all_objects, many=True)
        return Response(serializer.data)

you missed to forgot get function please refer to the docs https://www.django-rest-framework.org/tutorial/3-class-based-views/

CodePudding user response:

You probably got AttributeError while trying to get serializer.data. You sent Queryset object to the serializer not single instance of Post model. If you want to serialize multiple objects just pass many parameter as True. From docs;

To serialize a queryset or list of objects instead of a single object instance, you should pass the many=True flag when instantiating the serializer.

So, change your usage like;

posts = Post.objects.filter(body__search=term)
serializer = SearchSerializer(posts, many=True)

CodePudding user response:

try def get_serializer_class because in def post - serializer doesn't mean anything

  • Related