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

Django视图URL参数异常:UserBook ID显示为Book ID的问题解决

问题分析与解决方案

你的核心问题是视图参数混淆:表单提交时传递的是library.Book的ID,但book_review视图的URL设计期望接收readers.UserBook的ID,导致GET请求(如刷新页面)时因无法找到对应UserBook报错。以下是两种解决方案,可根据需求选择:


方案一:拆分视图(推荐,符合Django单一职责原则)

将「添加图书到个人收藏」和「展示个人图书详情」拆分为两个独立视图,彻底避免参数混淆:

1. 新增添加图书视图

在readers/views.py中添加专门处理添加逻辑的视图:

from django.shortcuts import get_object_or_404, redirect
from django.contrib import messages
from library.models import Book
from .models import UserBook

def add_to_my_books(request, book_id):
    if request.method == 'POST':
        book = get_object_or_404(Book, pk=book_id)
        # 检查用户是否已拥有该图书
        existing_user_book = UserBook.objects.filter(isbn=book.isbn, owner=request.user).first()
        
        if existing_user_book:
            messages.error(request, "You already have this book in your collection.")
            return redirect('readers:book_review', user_book_id=existing_user_book.id)
        else:
            # 创建新的UserBook
            user_book = UserBook.objects.create(
                cover=book.cover,
                title=book.title,
                publisher=book.publisher,
                isbn=book.isbn,
                nr_pages=book.nr_pages,
                synopsis=book.synopsis,
                author=", ".join([author.name for author in book.author.all()]),
                owner=request.user
            )
            return redirect('readers:book_review', user_book_id=user_book.id)
    # GET请求直接返回图书详情页
    return redirect('library:single_book', id=book_id)

2. 更新URL配置

修改readers/urls.py,新增添加图书的URL:

from django.urls import path
from . import views

app_name = 'readers'

urlpatterns = [
    path('add_to_my_books/<int:book_id>/', views.add_to_my_books, name='add_to_my_books'),
    path('review/my_books/<int:user_book_id>/', views.book_review, name='book_review'),
]

3. 调整表单提交地址

修改图书详情页的表单action,指向新增的视图:

<form action="{% url 'readers:add_to_my_books' book.id %}" method="post">
    {% csrf_token %}
    <button type="submit" class="start-reading-button">Add to My Books</button>
</form>

4. 简化原详情视图

让book_review只负责展示个人图书详情:

from django.shortcuts import get_object_or_404, render
from .models import UserBook

def book_review(request, user_book_id):
    user_book = get_object_or_404(UserBook, pk=user_book_id, owner=request.user)
    return render(request, 'readers/book_review.html', {'user_book': user_book})

方案二:修改现有视图(兼容两种场景,维持原有逻辑)

如果不想拆分视图,可修改book_review视图,通过请求方法区分参数类型:

1. 调整视图逻辑

from django.shortcuts import get_object_or_404, redirect, render
from django.contrib import messages
from library.models import Book
from .models import UserBook

def book_review(request, item_id):
    user_book = None

    if request.method == 'POST':
        # POST请求:item_id是Book的ID,处理添加逻辑
        book = get_object_or_404(Book, pk=item_id)
        existing_user_book = UserBook.objects.filter(isbn=book.isbn, owner=request.user).first()
        
        if existing_user_book:
            messages.error(request, "You already have this book in your collection.")
            user_book = existing_user_book
        else:
            user_book = UserBook.objects.create(
                cover=book.cover,
                title=book.title,
                publisher=book.publisher,
                isbn=book.isbn,
                nr_pages=book.nr_pages,
                synopsis=book.synopsis,
                author=", ".join([author.name for author in book.author.all()]),
                owner=request.user
            )
        # 重定向到正确的UserBook详情页
        return redirect('readers:book_review', item_id=user_book.id)
    else:
        # GET请求:item_id是UserBook的ID,直接查询展示
        user_book = get_object_or_404(UserBook, pk=item_id, owner=request.user)
        return render(request, 'readers/book_review.html', {'user_book': user_book})

2. 更新URL参数名

修改readers/urls.py中的参数名,使其更通用:

path('review/my_books/<int:item_id>/', views.book_review, name='book_review'),

3. 表单提交地址保持不变

表单仍传递Book的ID,视图会自动处理:

<form action="{% url 'readers:book_review' book.id %}" method="post">
    {% csrf_token %}
    <button type="submit" class="start-reading-button">Add to My Books</button>
</form>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 15:45:17