I’m developing a React application that retrieves a user’s followings from my Django backend API. However, I’m facing issues where the followings data is not being returned correctly.
API Response
When I make a GET request to the endpoint http://127.0.0.1:8000/api/chat/landing/
, I receive a JSON response structured like this:
{
"current_followings": [
{
"id": 1,
"username": "Amir",
"email": "[email protected]",
"full_name": "amirali",
"profile_photo": "/media/profile_photo/1000_F_244376003_1smlBNfWYSInMDUFymPuCcms6d1mOqaF_oU9kIP0.jpg",
"banner_photo": "/media/banner_photo/header.jpg",
"phone": null,
"address": "",
"bio": "",
"profile_views": 1
}
],
...
}
The response includes an array of current_followings
, each containing various fields like id
, username
, full_name
, and profile_photo
.
Django views.py
The view that handles this request is defined as follows:
from rest_framework.views import APIView
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from .models import Follower, BasicUserProfile # Assuming these are defined elsewhere
class ChatLandingView(APIView):
permission_classes = [IsAuthenticated]
def get(self, request):
try:
current_basic_user_profile = get_current_user_profile(request, User, BasicUserProfile)
current_followings = Follower.objects.filter(follower=current_basic_user_profile).select_related('following')
followings_serializer = BasicUserProfileSerializer([f.following for f in current_followings], many=True)
data = {
"current_followings": followings_serializer.data,
...
}
return Response(data, status=status.HTTP_200_OK)
except ObjectDoesNotExist:
return Response({"error": "Object not found"}, status=status.HTTP_404_NOT_FOUND)
except Exception as e:
return Response({"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
This view checks for authenticated users and fetches their followings using the Follower
model. It serializes the followings data before sending it back in the response.
React Code
In my React component, I’m using React Query to fetch the followings data:
import React from 'react';
import { useQuery } from '@tanstack/react-query';
import axios from 'axios';
const getToken = () => localStorage.getItem('authToken');
const fetchFollowings = async () => {
const token = getToken();
if (!token) {
throw new Error("No authentication token found. Please log in.");
}
const response = await axios.get('http://127.0.0.1:8000/api/chat/landing/', {
headers: { 'Authorization': `Bearer ${token}` },
});
return response.data.current_followings;
};
const ChatLanding = () => {
const { data: followings = [], error, isLoading } = useQuery({
queryKey: ['followings'],
queryFn: fetchFollowings,
});
return (
<div>
<h2>Your Followings</h2>
{isLoading && <p>Loading...</p>}
{error && <p>{error.message}</p>}
{followings.length === 0 && !isLoading && !error && (
<p>No followings found.</p>
)}
{followings.length > 0 && (
<ul>
{followings.map(following => (
<li key={following.id}>
<img src={following.profile_photo} alt={following.full_name} />
<p>{following.full_name} ({following.username})</p>
</li>
))}
</ul>
)}
</div>
);
};
export default ChatLanding;
Issue
- The
current_followings
array is not rendering correctly in my React component. Instead, I sometimes receive an error related to the authentication token. - I’ve verified that the token is being correctly stored and retrieved in the client-side code.
- When I check the console, I can see the API response is coming back successfully with a status of 200.
Question
What could be causing the issue with the followings not rendering as expected? Are there any adjustments I should make to either the Django view or the React code to resolve this?
Any insights would be greatly appreciated!
2
Answers
The issue was caused by an incorrect use of the serializer for the
current_followings
data. In the original code, the serializer was incorrectly applied to a list ofBasicUserProfile
objects, which was causing issues when trying to return the list of followings in the response.Here's how the problem was solved:
Correct Handling of
current_followings
: Thecurrent_followings
variable was obtained usingFollower.objects.filter(follower=current_basic_user_profile)
, but the data needed to be properly serialized before returning. Instead of serializing the entireFollower
objects, we needed to serialize thefollowing
field, which contains the user profiles being followed.Proper Use of
select_related
: To optimize the query,select_related
was used on thefollowing
field to avoid additional database queries when accessing the related user profiles. This ensures that thefollowing
user profiles are fetched along with theFollower
object, improving performance.Updated Serializer Application: The
BasicUserProfileSerializer
was used correctly to serialize thefollowing
user profiles rather than serializing theFollower
model itself.Updated Code:
Key Fixes:
Serialization of
following
Profiles:Follower
object, we serialized thefollowing
field (f.following
), which is the actual user profile that is being followed.Database Query Optimization with
select_related
:select_related('following')
is used in the query to fetch thefollowing
user profiles in the same database query, ensuring efficient access to the related user data.Result:
The updated code correctly returns a list of user profiles that the current user is following. The
current_followings
field now returns the serialized data of the users being followed, and the response structure is appropriately formatted.Token is being stored correctly and properly attached to the headers. What you are missing is the
authentication_classes
at your view:views.py
Although, I am not sure what kind of authentication package you have in place. Just be sure that the
Authentication
prefix is also correct.