The problem is this: I’m learning how to make a site on React+Django. And everything was fine until there was a need for a file that would take the book values on the page via API.
problem: does not go to the book page.
the problem is clearly in the routing of the address connection (ulrs… api..).
there is a connection with the backend itself and on the Catalog page the list of books and information from the database is received, but when using this code and trying to go to the book page, the console in the browser displays: api.js:12%20%0A%20GET%20http%3A//localhost:8000/catalog/books/fwegerwgergewf/%20404%20(Not%20Found)%0Aapi.js:12%20%0A%20GET%20http://localhost:8000/catalog/books/fwegerwgergewf/%20404%20(Not%20Found)
“`
and in the PyCharm terminal: 404. When viewing through the terminal:
>>> from catalog.models import Book
>>>
>>> book = Book.objects.filter(slug=’fwegerwgergewf’).first()
>>> if not book:
… print(“Book with such slug not found”)
… else:
… print(“Book found:”, book.title)
…
Book found: ацауца
>>>
Shows that the book and slug exist. The problem is either in slugs or in routing.
I have
from . import views
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework.status import HTTP_400_BAD_REQUEST, HTTP_200_OK
from .models import Book, Chapter
from .serializers import BookSerializer, ChapterSerializer
from django.shortcuts import get_object_or_404
from django.http import JsonResponse
import logging
from rest_framework.decorators import api_view
@api_view(['GET', 'POST'])
def Catalog(request):
if request.method == 'GET':
books = Book.objects.all()
serializer = BookSerializer(books, many=True)
return Response(serializer.data)
if request.method == 'POST':
serializer = BookSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=HTTP_200_OK)
return Response(serializer.errors, status=HTTP_400_BAD_REQUEST)
logger = logging.getLogger(__name__)
@api_view(['GET'])
def book_detail(request, slug):
try:
book = Book.objects.get(slug=slug)
serializer = BookSerializer(book)
return JsonResponse(serializer.data, safe=False)
except Book.DoesNotExist:
return JsonResponse({'error': 'Book not found'}, status=404)
@api_view(['GET'])
def chapter_list(request, book_slug):
book = get_object_or_404(Book, slug=book_slug)
chapters = Chapter.objects.filter(book=book)
serializer = ChapterSerializer(chapters, many=True)
return Response(serializer.data, status=HTTP_200_OK)
@api_view(['GET'])
def chapter_detail(request, book_slug, chapter_slug):
book = get_object_or_404(Book, slug=book_slug)
chapter = get_object_or_404(Chapter, slug=chapter_slug, book=book)
serializer = ChapterSerializer(chapter)
return Response(serializer.data, status=HTTP_200_OK)
Urls.py:
urlpatterns = [
path('', views.Catalog, name='catalog'),
path('books/<slug:slug>/', views.book_detail, name='book_detail'),
path('books/<slug:book_slug>/chapters/', views.chapter_list, name='chapter_list'),
path('books/<slug:book_slug>/chapters/<slug:chapter_slug>/', views.chapter_detail, name='chapter_detail'),
]
api.js:
import axios from 'axios';
const API_BASE_URL = 'http://localhost:8000'; // Замените на ваш фактический URL
// Получение списка книг
export const getCatalog = () => {
return axios.get(${API_BASE_URL}/catalog/);
};
// Получение деталей книги по slug
export const getBookDetail = (slug) => {
return axios.get(${API_BASE_URL}/catalog/books/${slug}/);
};
// Получение списка глав книги по slug книги
export const getChapterList = (bookSlug) => {
return axios.get(${API_BASE_URL}/catalog/books/${bookSlug}/chapters/);
};
// Получение деталей главы книги по slug книги и slug главы
export const getChapterDetail = (bookSlug, chapterSlug) => {
return axios.get(${API_BASE_URL}/catalog/books/${bookSlug}/chapters/${chapterSlug}/);
};
BookDetail.js:
import React, { useState, useEffect } from 'react';
import { getBookDetail } from '../api'; // Импорт функции для получения деталей книги
import { useParams } from 'react-router-dom'; // Для доступа к параметрам URL
const Book = () => {
const { slug } = useParams(); // Получаем slug из параметров URL
const [book, setBook] = useState(null); // Состояние для хранения данных книги
const [loading, setLoading] = useState(true); // Состояние загрузки
const [error, setError] = useState(null); // Состояние ошибки
useEffect(() => {
const fetchBookDetail = async () => {
try {
const response = await getBookDetail(slug); // Запрос к API
setBook(response.data); // Обновляем состояние с данными книги
} catch (error) {
setError('Ошибка при загрузке данных книги'); // Обрабатываем ошибки
} finally {
setLoading(false); // Завершаем загрузку
}
};
fetchBookDetail(); // Вызываем функцию при монтировании компонента
}, [slug]); // Зависимость от slug, чтобы обновлять данные при его изменении
if (loading) {
return <div>Загрузка...</div>; // Отображаем сообщение о загрузке
}
if (error) {
return <div>{error}</div>; // Отображаем сообщение об ошибке
}
if (!book) {
return <div>Книга не найдена</div>; // Если книга не найдена
}
return (
<div>
<h1>{book.title}</h1> {/* Отображаем заголовок книги */}
<p>{book.description}</p> {/* Отображаем описание книги */}
{/* Здесь можно добавить другие детали книги */}
</div>
);
};
export default Book;
It gives me a 404 error that it can’t find:
api.js:12%20%0A%20GET%20http%3A//localhost:8000/catalog/books/fwegerwgergewf/%20404%20(Not%20Found)%0Aapi.js:12%20%0A%20GET%20http://localhost:8000/catalog/books/fwegerwgergewf/%20404%20(Not%20Found)
should go to the book page and use the API to get the book data from the database
the page should display the book data
and everything should work via API