You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用React与Django交互:返回对象及通过ID获取对象数据

1. 如何从Django向React返回对象?

Django 端实现

用Django REST Framework(DRF)构建API是前后端分离场景下的标准方案,以下是具体步骤:

步骤1:安装并配置DRF

先安装依赖:

pip install djangorestframework

将rest_framework添加到项目settings.py的INSTALLED_APPS:

INSTALLED_APPS = [
    # ... 其他应用
    'rest_framework',
]

步骤2:定义示例模型

以书籍模型为例:

# your_app/models.py
from django.db import models

class Book(models.Model):
    title = models.CharField(max_length=100)
    author = models.CharField(max_length=50)
    publication_year = models.IntegerField()

    def __str__(self):
        return self.title

步骤3:编写序列化器

序列化器负责将Django模型转换为JSON格式:

# your_app/serializers.py
from rest_framework import serializers
from .models import Book

class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields = '__all__'

步骤4:编写API视图

创建返回对象列表的视图:

# your_app/views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from .models import Book
from .serializers import BookSerializer

class BookListView(APIView):
    def get(self, request):
        books = Book.objects.all()
        serializer = BookSerializer(books, many=True)
        return Response(serializer.data)

步骤5:配置URL

应用级路由:

# your_app/urls.py
from django.urls import path
from .views import BookListView

urlpatterns = [
    path('api/books/', BookListView.as_view(), name='book-list'),
]

项目根路由:

# project/urls.py
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('your_app.urls')),
]

跨域问题处理

由于React默认运行在localhost:3000,Django在localhost:8000,需解决跨域:

pip install django-cors-headers

配置settings.py:

INSTALLED_APPS = [
    # ... 其他应用
    'corsheaders',
]

MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',
    # ... 其他中间件
]

CORS_ALLOWED_ORIGINS = [
    "http://localhost:3000",
]

React 端实现

用fetch API请求数据并渲染:

// src/components/BookList.js
import React, { useState, useEffect } from 'react';

function BookList() {
  const [books, setBooks] = useState([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    fetch('http://localhost:8000/api/books/')
      .then(res => res.json())
      .then(data => {
        setBooks(data);
        setLoading(false);
      })
      .catch(err => {
        console.error('请求失败:', err);
        setLoading(false);
      });
  }, []);

  if (loading) return <div>加载中...</div>;

  return (
    <div className="book-list">
      <h2>书籍列表</h2>
      <ul>
        {books.map(book => (
          <li key={book.id}>
            {book.title} - {book.author} ({book.publication_year})
          </li>
        ))}
      </ul>
    </div>
  );
}

export default BookList;

2. 如何通过React将对象ID发送至Django,并返回该对象的数据?

Django 端实现

创建接收ID参数的详情API视图:

步骤1:编写详情视图

方式一:自定义APIView

# your_app/views.py
class BookDetailView(APIView):
    def get(self, request, book_id):
        try:
            book = Book.objects.get(id=book_id)
            serializer = BookSerializer(book)
            return Response(serializer.data)
        except Book.DoesNotExist:
            return Response({'error': '该书籍不存在'}, status=404)

方式二:DRF通用视图(更简洁)

from rest_framework.generics import RetrieveAPIView

class BookDetailView(RetrieveAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    lookup_url_kwarg = 'book_id'

步骤2:配置详情路由

# your_app/urls.py
urlpatterns = [
    path('api/books/', BookListView.as_view(), name='book-list'),
    path('api/books/<int:book_id>/', BookDetailView.as_view(), name='book-detail'),
]

React 端实现

方式一:URL路径传参(结合React Router)

先安装React Router:

npm install react-router-dom

编写详情组件:

// src/components/BookDetail.js
import React, { useState, useEffect } from 'react';
import { useParams } from 'react-router-dom';

function BookDetail() {
  const { bookId } = useParams();
  const [book, setBook] = useState(null);
  const [error, setError] = useState('');

  useEffect(() => {
    fetch(`http://localhost:8000/api/books/${bookId}/`)
      .then(res => {
        if (!res.ok) throw new Error('请求失败');
        return res.json();
      })
      .then(data => setBook(data))
      .catch(err => setError(err.message));
  }, [bookId]);

  if (error) return <div className="error">{error}</div>;
  if (!book) return <div>加载中...</div>;

  return (
    <div className="book-detail">
      <h2>{book.title}</h2>
      <p>作者:{book.author}</p>
      <p>出版年份:{book.publication_year}</p>
    </div>
  );
}

export default BookDetail;

配置路由:

// src/App.js
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import BookList from './components/BookList';
import BookDetail from './components/BookDetail';

function App() {
  return (
    <Router>
      <div className="App">
        <Routes>
          <Route path="/" element={<BookList />} />
          <Route path="/book/:bookId" element={<BookDetail />} />
        </Routes>
      </div>
    </Router>
  );
}

export default App;

方式二:查询参数传递ID(点击按钮请求)

在列表组件中添加详情按钮:

// src/components/BookList.js
import React, { useState, useEffect } from 'react';

function BookList() {
  const [books, setBooks] = useState([]);
  const [selectedBook, setSelectedBook] = useState(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    fetch('http://localhost:8000/api/books/')
      .then(res => res.json())
      .then(data => {
        setBooks(data);
        setLoading(false);
      })
      .catch(err => {
        console.error('请求失败:', err);
        setLoading(false);
      });
  }, []);

  const fetchBookDetail = (bookId) => {
    fetch(`http://localhost:8000/api/books/detail/?id=${bookId}`)
      .then(res => res.json())
      .then(data => setSelectedBook(data))
      .catch(err => console.error('获取详情失败:', err));
  };

  if (loading) return <div>加载中...</div>;

  return (
    <div className="book-list">
      <h2>书籍列表</h2>
      <ul>
        {books.map(book => (
          <li key={book.id}>
            {book.title} - {book.author}
            <button onClick={() => fetchBookDetail(book.id)}>查看详情</button>
          </li>
        ))}
      </ul>

      {selectedBook && (
        <div className="book-detail">
          <h3>书籍详情</h3>
          <p>{selectedBook.title} - {selectedBook.author} ({selectedBook.publication_year})</p>
        </div>
      )}
    </div>
  );
}

export default BookList;

对应的Django视图:

# your_app/views.py
class BookDetailByQueryView(APIView):
    def get(self, request):
        book_id = request.query_params.get('id')
        if not book_id:
            return Response({'error': '缺少ID参数'}, status=400)
        try:
            book = Book.objects.get(id=book_id)
            serializer = BookSerializer(book)
            return Response(serializer.data)
        except Book.DoesNotExist:
            return Response({'error': '该书籍不存在'}, status=404)

添加路由:

# your_app/urls.py
urlpatterns = [
    # ... 其他路由
    path('api/books/detail/', BookDetailByQueryView.as_view(), name='book-detail-query'),
]

内容的提问来源于stack exchange,提问作者Mathew O'Sullivan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 11:46:07