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

Next.js+Django+Spotify全栈应用创建房间后404问题求助

Next.js + Django 全栈应用房间创建后跳转404问题排查与修复

我正在开发基于Next.js、Django和Spotify API的全栈应用,点击创建房间按钮后,房间已成功生成唯一code,但跳转后提示房间不存在,返回GET http://127.0.0.1:8000/room/f5428fc5 404 (Not Found)。尝试修改fetch路径无效,相关代码如下:


前端代码

create.js 关键逻辑

const handleRoomButtonPressed = () => {
    const requestOptions = {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        votes_to_skip: votesToSkip,
        guest_can_pause: guestCanPause,
      }),
    };
    fetch("/api/create-room", requestOptions)
      .then((response) => response.json())
      .then((data) => router.push("/room/" + data.code))
      .catch((error) => setErrorMsg("Error creating room..."));
  };

room.js 关键逻辑

const [roomDetails, setRoomDetails] = useState({
    votesToSkip: 2,
    guestCanPause: false,
    isHost: false,
    spotifyAuthenticated: false,
    song: {},
  });

 const { roomCode } = router.query; 

  const getRoomDetails = () => {
    fetch("/api/get-room" + "?code=" + roomCode)
      .then((response) => {
        if (!response.ok) {
          leaveRoomCallback();
          navigate("/");
        }
        return response.json();
      })
      .then((data) => {
        setRoomDetails({
          votesToSkip: data.votes_to_skip,
          guestCanPause: data.guest_can_pause,
          isHost: data.is_host,
        });
        if (data.is_host) {
          authenticateSpotify();
        }
      });
  };

Django 后端代码

api/urls.py

from django.urls import path
from .views import RoomView, CreateRoomView, GetRoom, JoinRoom, UserInRoom, LeaveRoom, UpdateRoom

urlpatterns = [
    path('room', RoomView.as_view()),
    path('create-room', CreateRoomView.as_view()), 
    path('get-room', GetRoom.as_view()),
    path('join-room', JoinRoom.as_view()),
    path('user-in-room', UserInRoom.as_view()),
    path('leave-room', LeaveRoom.as_view()),
    path('update-room', UpdateRoom.as_view())
]

api/views.py 关键类

class GetRoom(APIView):
    serializer_class = RoomSerializer
    lookup_url_kwarg = 'code'

    def get(self, request, format=None):
        code = request.GET.get(self.lookup_url_kwarg)
        if code is not None:
            room = Room.objects.filter(code=code).first()
            if room is not None:
                data = RoomSerializer(room).data
                data['is_host'] = self.request.session.session_key == room.host
                return Response(data, status=status.HTTP_200_OK)
            return Response({'Room Not Found': 'Invalid Room Code.'}, status=status.HTTP_404_NOT_FOUND)
        return Response({'Bad Request': 'Code parameter not found in request'}, status=status.HTTP_400_BAD_REQUEST)


class CreateRoomView(APIView):
    serializer_class = CreateRoomSerializer

    def post(self, request, format=None):
        if not self.request.session.exists(self.request.session.session_key):
            self.request.session.create()

        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            guest_can_pause = serializer.data.get('guest_can_pause')
            votes_to_skip = serializer.data.get('votes_to_skip')
            host = self.request.session.session_key

            code = str(uuid.uuid4())[:8]  

            room = Room(host=host, guest_can_pause=guest_can_pause, votes_to_skip=votes_to_skip, code=code)
            room.save()
            self.request.session['room_code'] = room.code
            return Response(RoomSerializer(room).data, status=status.HTTP_201_CREATED)

        return Response({'Bad Request': 'Invalid data...'}, status=status.HTTP_400_BAD_REQUEST)

api/models.py

from django.db import models
import string 
import random

def generate_unique_code():
    length = 6

    while True:
        code = ''.join(random.choices(string.ascii_uppercase, k=length))
        if Room.objects.filter(code=code).count() == 0:
            break

        return code


class Room(models.Model):
    code = models.CharField(max_length=8, default="", unique=True)
    host = models.CharField(max_length=50, unique=True)
    guest_can_pause = models.BooleanField(null=False, default=False)
    votes_to_skip = models.IntegerField(null=False, default=1)
    created_at = models.DateTimeField(auto_now_add=True)

问题排查与修复方案

1. 核心问题:前端路由与后端路由不匹配

404的直接原因是Django未配置/room/{code}的路由,但前端跳转路径为/room/{code};同时Next.js页面结构未对应动态路由规则。

修复步骤:

  • Next.js 页面调整:将room.js重命名为[roomCode].js,放在pages/room/目录下(无目录则新建),让Next.js正确识别动态路由参数roomCode。
  • Django 路由补充:在frontend/urls.py(或主项目urls.py)中添加前端页面路由,让Django处理/room/{code}请求:
from django.urls import path
from .views import room_page  # 需实现渲染前端房间页面的视图

urlpatterns = [
    # ... 现有路由
    path('room/<str:code>', room_page),
]

若使用Next.js SSR/静态导出,需配置Django将所有前端路由转发至Next.js入口文件(如index.html)。

2. generate_unique_code函数bug(潜在问题)

models中generate_unique_code的return code写在if块内,导致仅当生成的code已存在时才返回,否则陷入无限循环。修复如下:

def generate_unique_code():
    length = 6
    while True:
        code = ''.join(random.choices(string.ascii_uppercase, k=length))
        if Room.objects.filter(code=code).count() == 0:
            return code  # 找到唯一code后直接返回

3. 确认room.js参数获取逻辑

修改页面为[roomCode].js后,在useEffect中触发getRoomDetails,确保参数存在时才请求:

useEffect(() => {
  if (roomCode) {
    getRoomDetails();
  }
}, [roomCode]);

4. 验证API请求路径

通过浏览器开发者工具Network标签,确认fetch("/api/get-room?code=" + roomCode)的实际请求URL与参数是否正确传递,确保API前缀(如/api/)配置无误。


内容的提问来源于stack exchange,提问作者amirlasalle

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 06:04:59