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

Django DetailView页面提交表单遇405 Method Not Allowed错误求助

Django表单提交405 Method Not Allowed问题解决

问题根源

你遇到的405错误是因为:

  • 表单未指定action属性,默认提交到当前DetailView的URL,但DetailView默认仅支持GET请求,不处理POST方法
  • 你编写的get_score处理视图,要么未配置对应的URL路由,要么表单没指向该视图的地址

解决方案一:单独使用处理视图

1. 配置URL路由

在urls.py中添加get_score的路由,同时传递赛事ID(用于处理完分数后重定向回详情页):

from django.urls import path
from .views import TournamentDetailView, get_score

urlpatterns = [
    path('tournament/<int:pk>/', TournamentDetailView.as_view(), name='tournament-detail'),
    path('tournament/<int:pk>/submit-score/', get_score, name='submit-score'),
]

2. 修改表单HTML

指定表单提交的action为上述路由,同时添加隐藏字段传递选手ID(以便处理分数时关联到对应选手):

<h7><img style="width:2rem; height:2rem" src="{{ player.avatar.url }}"> {{player}}</h7>
<form method="POST" action="{% url 'submit-score' tournament.pk %}">
    {% csrf_token %}
    <input type="hidden" name="player_id" value="{{ player.id }}">
    <input style="width:2rem" type="text" id="{{player}}" name="score">
    <input type="submit" value="OK">
</form>
{{ val }}

注:tournament.pk需替换为你模板中实际的赛事对象变量名

3. 完善get_score视图

处理分数逻辑,并在完成后重定向回详情页:

from django.shortcuts import render, redirect, get_object_or_404
from .forms import GetScoreForm
from .models import Player, Tournament

def get_score(request, pk):
    tournament = get_object_or_404(Tournament, pk=pk)
    if request.method == 'POST':
        form = GetScoreForm(request.POST)
        if form.is_valid():
            score_val = form.cleaned_data.get("score")
            player_id = request.POST.get('player_id')
            player = get_object_or_404(Player, id=player_id)
            # 在这里编写你的分数处理逻辑,比如保存到数据库
            # player.score = score_val
            # player.save()
            # 处理完成后重定向回赛事详情页
            return redirect('tournament-detail', pk=pk)
    else:
        form = GetScoreForm()
    return render(request, 'tournamentdetailview.html', {'form': form, 'tournament': tournament})

解决方案二:在DetailView中直接处理POST请求

无需额外创建视图,直接在DetailView类中重写post方法:

1. 修改DetailView类

from django.views.generic.detail import DetailView
from django.shortcuts import get_object_or_404
from .models import Tournament, Player
from .forms import GetScoreForm

class TournamentDetailView(DetailView):
    model = Tournament
    template_name = 'tournamentdetailview.html'

    # 把表单加入上下文,供模板调用
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['form'] = GetScoreForm()
        return context

    # 重写post方法处理表单提交
    def post(self, request, *args, **kwargs):
        self.object = self.get_object()
        form = GetScoreForm(request.POST)
        if form.is_valid():
            score_val = form.cleaned_data.get("score")
            player_id = request.POST.get('player_id')
            player = get_object_or_404(Player, id=player_id)
            # 编写分数处理逻辑
            # player.score = score_val
            # player.save()
            # 重定向回当前页面,避免重复提交
            return self.get(request, *args, **kwargs)
        # 表单验证失败时,返回页面并携带错误表单
        context = self.get_context_data(**kwargs)
        context['form'] = form
        return self.render_to_response(context)

2. 调整表单HTML

此时表单无需指定action,默认提交到当前DetailView的URL,只需保留隐藏字段传递选手ID:

<h7><img style="width:2rem; height:2rem" src="{{ player.avatar.url }}"> {{player}}</h7>
<form method="POST">
    {% csrf_token %}
    <input type="hidden" name="player_id" value="{{ player.id }}">
    <input style="width:2rem" type="text" id="{{player}}" name="score">
    <input type="submit" value="OK">
</form>
{{ val }}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 20:45:34