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