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.
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": "Amir@amir.ir",
"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
.
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.
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;
current_followings
array is not rendering correctly in my React component. Instead, I sometimes receive an error related to the authentication token.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!
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 of BasicUserProfile
objects, which was causing issues when trying to return the list of followings in the response.
Correct Handling of current_followings
:
The current_followings
variable was obtained using Follower.objects.filter(follower=current_basic_user_profile)
, but the data needed to be properly serialized before returning. Instead of serializing the entire Follower
objects, we needed to serialize the following
field, which contains the user profiles being followed.
Proper Use of select_related
:
To optimize the query, select_related
was used on the following
field to avoid additional database queries when accessing the related user profiles. This ensures that the following
user profiles are fetched along with the Follower
object, improving performance.
Updated Serializer Application:
The BasicUserProfileSerializer
was used correctly to serialize the following
user profiles rather than serializing the Follower
model itself.
class ChatLandingView(APIView):
permission_classes = [IsAuthenticated]
def get(self, request):
try:
current_basic_user = get_current_user(request, User)
current_basic_user_profile = get_current_user_profile(request, User, BasicUserProfile)
topics_to_follow = get_topics_to_follow(Topic, ObjectDoesNotExist, random)
who_to_follow = get_who_to_follow(BasicUserProfile)
# Adjusted field names based on your Follower model
current_followings = Follower.objects.filter(follower=current_basic_user_profile).select_related('following')
# Serialize the data
user_serializer = BasicUserProfileSerializer(current_basic_user_profile)
topics_serializer = TopicSerializer(topics_to_follow, many=True)
followings_serializer = BasicUserProfileSerializer([f.following for f in current_followings], many=True)
who_to_follow_serializer = BasicUserProfileSerializer(who_to_follow, many=True)
data = {
"current_basic_user": user_serializer.data,
"current_basic_user_profile": user_serializer.data,
"who_to_follow": who_to_follow_serializer.data,
"topics_to_follow": topics_serializer.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)
Serialization of following
Profiles:
Follower
object, we serialized the following
field (f.following
), which is the actual user profile that is being followed.followings_serializer = BasicUserProfileSerializer([f.following for f in current_followings], many=True)
Database Query Optimization with select_related
:
select_related('following')
is used in the query to fetch the following
user profiles in the same database query, ensuring efficient access to the related user data.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.