I am working on a web app with Django Rest Framework and React.
When I make a request to Django via http://localhost:8000/api/v1/auth/users/daniel/
for a User’s profile, it returns JSON but, instead of returning a response of the userProfile as the data value, it returns some react/vite HTML code.
<!doctype html>
<html lang="en">
<head>
<script type="module">
import RefreshRuntime from "/@react-refresh"
RefreshRuntime.injectIntoGlobalHook(window)
window.$RefreshReg$ = () => {}
window.$RefreshSig$ = () => (type) => type
window.__vite_plugin_react_preamble_installed__ = true
</script>
<script type="module" src="/@vite/client"></script>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.jsx?t=1717529669140"></script>
</body>
</html>
Here is the DRF response of what I am expecting to see in the Reac Axios response.
urls.py
urlpatterns = [
.....,
path('api/v1/auth/users/<str:username>/', views.UserProfileByUsernameView.as_view(), name='user-profile-by-username'),
]
views.py
class UserProfileByUsernameView(APIView):
permission_classes = [AllowAny]
def get(self, request, username):
user = get_object_or_404(User, username=username)
profile_serializer = UserProfileSerializer(user.userprofile)
profile_data = profile_serializer.data
profile_data['username'] = user.username
profile_data['email'] = user.email
return Response(profile_data, status=status.HTTP_200_OK)
serializers.py
class UserProfileSerializer(serializers.ModelSerializer):
username = serializers.CharField(source='user.username', read_only=True)
email = serializers.EmailField(source='user.email', read_only=True)
class Meta:
model = UserProfile
fields = '__all__'
profile-page.jsx
const ProfilePage = () => {
const { username } = useParams();
const [userProfile, setUserProfile] = useState(null);
const [isOwnProfile, setIsOwnProfile] = useState(false);
const loggedInUsername = localStorage.getItem('username');
useEffect(() => {
const fetchUserProfile = async () => {
try {
const response = await axios.get(`/api/v1/auth/users/${username}/`, {
headers: {
'Authorization': `Bearer ${userToken()}`,
},
});
console.log(response)
setUserProfile(response.data);
setIsOwnProfile(loggedInUsername === username);
} catch (error) {
console.error('Error fetching user profile:', error);
}
};
fetchUserProfile();
}, [username, loggedInUsername]);
console.log(userProfile);
if (!userProfile) {
return (
<div className="flex justify-center items-center h-screen">
<div className="text-lg font-semibold">Loading...</div>
</div>
);
}
I have tried searching through the developer tools, simplifying the model to be returned and clearing the cache as I was seeing a 204 reponse at one point but I had no luck.
2
Answers
To solve the problem, I had to prepend
http://127.0.0.1:8000
to the API URL.http://127.0.0.1:8000/api/v1/auth/users/${username}
.Slightly embarrassing, but that's the life of a developer sometimes.
A DRF view does not per se renders to JSON. In fact the page you are looking at is not JSON. No, it is HTML that shows some JSON data.
You can tell DRF what format to use by using the HTTP Content-Type header or by adding a value for the
format
in the querystring, so for example: