I'm working on Django React project. I have made user and project models in django. I can get access to project list page, but i am stuck trying get access to project page. Another thing is, when i use link on page with list of projects, it sends to http://localhost:3000/projects/undefined.
projectlist page: http://localhost:3000/projects/
project page: http://localhost:3000/projects/skyscrapper
Console:
GET http://localhost:8000/api/projects/undefined/ 500 (Internal Server Error)
Terminal:
base.models.Project.DoesNotExist: Project matching query does not exist.
[07/Dec/2022 20:47:10] "GET /api/projects/undefined/ HTTP/1.1" 500 101255
project.js
import { React, useState, useEffect } from 'react';
import axios from 'axios';
import { Row, Col, Image, ListGroup } from 'react-bootstrap'
import './index.css'
import './bootstrap.min.css'
function Project() {
// projects is the data, setprojects is a function that sets the value of projects
const [project, setProject] = useState([]);
useEffect(() => {
const fetchproject = async({slug}) => {
try {
const res = await axios.get(`http://localhost:8000/api/projects/${slug}`);
setProject(res.data);
} catch (err) {}
};
const slugData = window.location.href.split("/");
fetchproject(slugData[slugData.length-1]);// add your slug value in this method as an argument
}, []);
return (
<div>
<Row className="my-1 p-4">
<Col xs={3} sm={2} md={2} lg={1} >
<Image className="p-1 rounded-circle bg-dark mx-auto d-block" style={{width: 100, height: 100}} src={project.image} fluid />
<ListGroup variant="flush" >
<ListGroup.Item>
<h3 >{project.name}</h3>
</ListGroup.Item>
<ListGroup.Item style={{fontSize: 12}}>
<p>{project.description}</p>
</ListGroup.Item>
</ListGroup>
</Col>
</Row>
</div>
)
}
export default Project;
App.js
import React from "react";
import { BrowserRouter, Routes, Route } from 'react-router-dom'
import Header from './components/header'
import Footer from './components/footer'
import Users from './pages/users'
import Projects from './pages/projects'
import User from './pages/user'
import Project from './pages/project'
function App() {
return (
<>
<Header/>
<BrowserRouter>
<Routes>
<Route path='users/' element={<Users />} />
<Route path='projects/' element={<Projects />} />
<Route path="/projects/:id" element={<Project />} />
<Route path="/users/:id" element={<User />} />
</Routes>
</BrowserRouter>
<Footer/>
</>
);
}
export default App;
urls.py
from django.urls import path
from .views import getRoutes, UserListView, ProjectListView, projectview
urlpatterns = [
path('', getRoutes, name='routes'),
path('users/', UserListView.as_view(), name='routes'),
path('projects/', ProjectListView.as_view(), name='routes'),
path('projects/<slug:slug>/', projectview, name='routes'),
view.py
from django.shortcuts import render
from django.http import JsonResponse
from .models import Profile, Project
from django.views.generic.list import ListView
from rest_framework import generics
from rest_framework.response import Response
from rest_framework.decorators import api_view
from .serializers import UserSerializer, ProjectSerializer
@api_view(['GET'])
def getRoutes(request):
routes = [
'/api/projects/',
'/api/users/',
'/api/projects/<str:name>',
'/api/users/<id>',
]
return Response(routes)
class UserListView(generics.ListAPIView):
serializer_class = UserSerializer
def get_queryset(self):
queryset = Profile.objects.all()
return queryset.all()
class ProjectListView(generics.ListAPIView):
model = Project
serializer_class = ProjectSerializer
def get_queryset(self):
queryset = self.model.objects.all()
return queryset
@api_view(['GET'])
def projectview(request, **kwargs):
project = Project.objects.get(slug=kwargs.get('slug'))
serializer = ProjectSerializer(project)
return Response(serializer.data)
Have a nice day, everyone!
CodePudding user response:
It seems you are trying to access a non-existent instance. Try implementing this method when accessing resources: https://docs.djangoproject.com/en/4.1/topics/http/shortcuts/#get-object-or-404
CodePudding user response:
There were couple of mistakes in my code, but main was, that i forgot to add slug field to serialazier class.
serializers.py
class ProjectSerializer(serializers.Serializer):
name = serializers.CharField()
slug = serializers.SlugField()
employer = serializers.EmailField()
description = serializers.CharField()
required_skills = serializers.CharField()
project.py that worked for me:
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import { Row, Col, Image, ListGroup } from 'react-bootstrap'
import { useParams } from 'react-router-dom'
import './index.css'
import './bootstrap.min.css'
function Project({ match }) {
const [project, setProject] = useState([])
const { slug } = useParams();
console.log(slug);
useEffect (() => {
async function fetchProject() {
const { data } = await axios.get(`http://127.0.0.1:8000/api/projects/${slug}`);
setProject(data)
}
fetchProject()
}, [slug])
return (
<div>
<Row className="my-1 p-4">
<Col xs={3} sm={2} md={2} lg={1} >
<Image className="p-1 rounded-circle bg-dark mx-auto d-block" style={{width: 100, height: 100}} src={project.image} fluid />
<ListGroup variant="flush" >
<ListGroup.Item>
<h3 >{project.name}</h3>
</ListGroup.Item>
<ListGroup.Item style={{fontSize: 12}}>
<p>{project.description}</p>
</ListGroup.Item>
</ListGroup>
</Col>
</Row>
</div>
)
}
export default Project;
<Route path="/projects/:slug" element={} /> instead of <Route path="/projects/:id" element={} /> in app.js
import React from "react";
import { BrowserRouter, Routes, Route } from 'react-router-dom'
import Header from './components/header'
import Footer from './components/footer'
import Users from './pages/users'
import Projects from './pages/projects'
import User from './pages/user'
import Project from './pages/project'
function App() {
return (
<>
<Header/>
<BrowserRouter>
<Routes>
<Route path='users/' element={<Users />} />
<Route path='projects/' element={<Projects />} />
<Route path="/projects/:slug" element={<Project />} />
<Route path="/users/:id" element={<User />} />
</Routes>
</BrowserRouter>
<Footer/>
</>
);
}
export default App;