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

Django资产管理系统中“Confirm Changes”按钮触发404错误排查

问题描述

我正在开发一个基于Django的简易资产管理程序,在assman.html中有处理资产详情修改的代码,同时有唤起该表单的"change"按钮代码,两个场景都调用views.py中的assman_handler()函数。点击"change"和"delete"按钮时函数可正常执行,但点击"Confirm Changes"按钮时直接返回404错误:

Page not found (404)
No Asset matches the given query.
Request Method: POST
Request URL: http://localhost:8000/assman_handler
Raised by: assman.views.assman_handler

相关代码如下:

修改资产表单代码(assman.html)

{%if change_form%}
<h2>Change Asset Details</h2>
<form method="POST" name='change_asset' action="{% url 'assman_handler' %}">
  {% csrf_token %}
  {% if NoSuchUser %}
  <script>window.alert('No such user!')</script>
  {% endif %}
  <table>
    <tr>
      <td><label for="qrcode">QR Code:</label></td>
      <td><input type="text" name="qrcode" class="form-control" id="qrcode" maxlength='13' value = "{{ asset.qrcode }}" required></td>
    </tr>
    <tr>
      <td><label for ="name" required>Asset Name: </label></td>
      <td><input type="text" name="name" class='form-control' value = "{{ asset.name }}" required ></input></td>
    </tr>
    <tr>
      <td><label for="user_id">User:</label></td>
      <td>
        <select name="user_id">
          {%for user in users%}
            <option value="{{ user.id }}" {% if user.id == asset.user.id %}selected{% endif %}>{{ user.username }}</option> </option>
          {%endfor%}
        </select>
      </td>
    </tr>
    <tr>
      <td><label for="checkout_date">Checkout Date:</label></td>
      <td><input type="date" name="checkout_date" class="form-control" id="checkout_date" value = "{{asset.checkout_date}}" required></td>
    </tr>
    <tr>
      <td><label for="location">Location:</label></td>
      <td><input name="location" class="form-control" id="location" value = "{{asset.location}}" required></td>
    </tr>
  </table>
  <button type="submit" class="btn btn-primary" value='confirm' name='value'>Confirm Changes</button>
</form>
{%endif%}

唤起修改表单的按钮代码(assman.html)

<h2>Matched Items</h2>
{%for asset in matches%}
<li> {{asset.name}} at {{asset.location}} owned by {{asset.user}} expiring on {{asset.checkout_date}}</li>
<form method="POST" action="{% url 'assman_handler' %}" style="display: inline-block;">
    {% csrf_token %}
    <input type="submit" name="value" value="change" id="change-btn">
    <input type="hidden" value={{asset.id}} name='asset_id'>
  </form>
  <form method='POST' action="{% url 'assman_handler' %}" style="display: inline-block;">
    {% csrf_token %}
    <input type="submit" value="delete" name='value' >
    <input type="hidden" name = "asset_id" value={{asset.id}} name='asset'>
  </form>
</li>
{%endfor%}

视图函数代码(views.py)

def assman_handler(request):
    print(request.POST.get('value'))
    #Setting variable values
    assid = request.POST.get('asset_id')
    asset = Asset.objects.get(id=assid)
    if request.POST.get('value') == 'change': return render(request, 'assman.html', {'users': User.objects.all(),'change_form': True, 'asset': asset, 'allass': Asset.objects.all()})
    elif request.POST.get('value') == 'confirm':
        # Behaviour for changing assets
        redirect('assman')
    elif request.POST.get('value') == 'delete':
        asset.delete()
    redirect('assman')

Asset模型代码(models.py)

class Asset(models.Model):
    name = models.CharField(max_length=255)
    location = models.CharField(max_length=255)
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    checkout_date = models.DateField()
    qrcode = models.CharField(max_length=13)
    objects = models.Manager()
问题原因
  1. 缺少资产ID传递:点击"Confirm Changes"提交修改表单时,表单未携带asset_id隐藏字段,导致assid = request.POST.get('asset_id')获取到的值为None。
  2. 无异常处理逻辑:调用Asset.objects.get(id=assid)时,assid为None会触发Asset.DoesNotExist异常,Django默认将该异常转换为404错误。
  3. 视图逻辑顺序错误:在判断操作类型之前就执行了资产查询代码,导致确认修改的请求还没进入分支判断就触发了异常。
修复方案

步骤1:给修改表单添加asset_id隐藏字段

修改assman.html中的修改资产表单,在{% csrf_token %}下方添加隐藏字段传递当前资产ID:

{%if change_form%}
<h2>Change Asset Details</h2>
<form method="POST" name='change_asset' action="{% url 'assman_handler' %}">
  {% csrf_token %}
  <!-- 添加资产ID隐藏字段 -->
  <input type="hidden" name="asset_id" value="{{ asset.id }}">
  {% if NoSuchUser %}
  <script>window.alert('No such user!')</script>
  {% endif %}
  <!-- 剩余表单内容保持不变 -->

步骤2:调整视图函数逻辑并添加异常处理

修改views.py中的assman_handler函数,先判断操作类型,再按需查询资产,同时处理资产不存在的情况:

from django.shortcuts import redirect, render
from django.http import Http404

def assman_handler(request):
    action = request.POST.get('value')
    print(action)
    
    if action == 'change':
        assid = request.POST.get('asset_id')
        try:
            asset = Asset.objects.get(id=assid)
        except Asset.DoesNotExist:
            raise Http404("资产不存在")
        return render(request, 'assman.html', {
            'users': User.objects.all(),
            'change_form': True, 
            'asset': asset, 
            'allass': Asset.objects.all()
        })
    elif action == 'confirm':
        assid = request.POST.get('asset_id')
        try:
            asset = Asset.objects.get(id=assid)
            # 执行资产修改逻辑
            asset.qrcode = request.POST.get('qrcode')
            asset.name = request.POST.get('name')
            asset.user_id = request.POST.get('user_id')
            asset.checkout_date = request.POST.get('checkout_date')
            asset.location = request.POST.get('location')
            asset.save()
        except Asset.DoesNotExist:
            raise Http404("资产不存在")
        return redirect('assman')
    elif action == 'delete':
        assid = request.POST.get('asset_id')
        try:
            asset = Asset.objects.get(id=assid)
            asset.delete()
        except Asset.DoesNotExist:
            raise Http404("资产不存在")
        return redirect('assman')
    # 处理未知操作
    return redirect('assman')

步骤3:修正删除表单的重复name属性

删除按钮的表单中,隐藏字段存在重复name属性,修改为唯一的name="asset_id":

<form method='POST' action="{% url 'assman_handler' %}" style="display: inline-block;">
    {% csrf_token %}
    <input type="submit" value="delete" name='value' >
    <input type="hidden" name="asset_id" value="{{asset.id}}">
</form>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 19:15:15