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

如何在Django同一视图中处理两个POST请求且避免MultiValueDictKeyError?

解决MultiValueDictKeyError:让视图兼容搜索和收藏两个POST请求

问题根源分析

你的问题出在两个核心点上:

  1. 收藏表单提交目标错误:页面里收藏按钮的<form>没有指定action属性,默认会提交到当前页面的URL(也就是/search,对应search视图)。但search视图里直接用request.POST['search']获取搜索参数,收藏请求里根本没有这个参数,自然触发了MultiValueDictKeyError。
  2. 搜索视图参数获取不健壮:直接用字典下标[]访问POST参数,一旦参数不存在就会报错,应该用更安全的写法。

分步解决方案

1. 修正收藏表单的提交目标

首先确保urls.py给anime视图设置好命名URL,方便模板调用:

# urls.py
from django.urls import path
from . import views

urlpatterns = [
    path('search/', views.search, name='search'),
    path('anime/add/', views.anime, name='add-anime-to-wishlist'),
]

然后修改HTML里的收藏表单,指定action为上述命名URL,同时修正原代码里的标签嵌套错误:

{% if user.is_authenticated %}
    {% if animes %}
        {% for anime in animes %}
            <form method="post" action="{% url 'add-anime-to-wishlist' %}">
                {% csrf_token %}
                <section>
                    <div class="row">
                        <div class="col-md-4 col-sm-6 col-lg-3">
                            <div class="card">
                                <div class="card-body text-center">
                                    <p class="card-title"><b>{{anime.Title}}</b></p>
                                    <hr>
                                    <p class="card-text">Episodes: <b>{{anime.Episodes}}</b></p>
                                    <img src="{{anime.Image}}" />
                                </div>
                            </div>
                            <input type="hidden" value="{{anime.Id}}" name="anime_id">
                            <button type="submit" class="btn btn-outline-primary" style="font-size:18px; border-radius: 50%">★</button>
                        </div>
                    </div>
                </section>
            </form>
        {% endfor %}
    {% endif %}
{% endif %}

2. 让搜索视图的参数获取更安全

把search视图里直接取request.POST['search']的写法,改成用get()方法,避免参数缺失时报错:

def search(request):
    animes = []
    if request.method == 'POST':
        # 安全获取搜索参数,默认值为空字符串
        search_query = request.POST.get('search', '')
        if search_query:  # 只有搜索内容非空时才发起API请求
            animes_url = 'https://api.jikan.moe/v3/search/anime'
            search_params = {
                'q': search_query,
                'limit': 6,
                'page': 1
            }
            r = requests.get(animes_url, params=search_params)
            results = r.json().get('results', [])
            for result in results:
                animes_data = {
                    'Id' : result["mal_id"],
                    'Title' : result["title"],
                    'Episodes' : result["episodes"],
                    'Image' : result["image_url"]
                }
                animes.append(animes_data)
        else:
            # 把提示消息传到模板显示,而不是用print
            messages.info(request, "请输入搜索关键词")
    context = {
        'animes' : animes
    }
    return render(request,'search.html', context)

3. 优化收藏视图的容错性

anime视图里直接用Anime.objects.get(id=anime_id)可能触发DoesNotExist异常,加上容错处理更稳妥:

from django.shortcuts import get_object_or_404

def anime(request):
    if request.method == "POST":
        anime_id = request.POST.get("anime_id")
        # 找不到对应Anime时返回404,避免崩溃
        anime = get_object_or_404(Anime, id=anime_id)
        request.user.profile.animes.add(anime)
        messages.success(request, f'{anime} added to wishlist.')
        return redirect('search')  # 用URL名称重定向,更健壮
    # GET请求访问时直接跳回搜索页
    return redirect('search')

额外小提醒

  • 注意HTML标签的闭合顺序,原代码里的嵌套错误可能导致页面布局异常;
  • 调用外部API时建议加上网络请求、JSON解析的异常处理,避免视图因外部服务故障崩溃。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 16:19:09