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

Django Admin修改Cursuri字段后删除关联Note数据的异常问题

Django Admin课程名称修改后关联成绩删除功能修复

原代码存在的问题

  • 课程名称未更新:修改titlu_curs后没有调用.save()方法,仅修改了内存中的模型实例,数据库未同步变更。
  • 确认表单逻辑失效:模板表单的action路径硬编码错误,且未传递必要标识参数,导致提交后无法识别用户的"Yes/No"选择,无法执行对应的数据处理逻辑。
  • 缺失确认后分支处理:原change_view仅处理第一次修改提交的请求,未响应确认页的提交操作,导致跳转和数据处理均不符合预期。

修复方案

1. 修正CursuriAdmin的change_view方法

from django.shortcuts import HttpResponseRedirect
from django.urls import reverse

class CursuriAdmin(admin.ModelAdmin):
    list_filter = ("an","semestru","credite", )
    list_display=("id_curs","titlu_curs","an","semestru","credite",)
    
    def change_view(self, request, object_id, form_url='', extra_context=None):
        # 处理确认页面的提交请求
        if request.method == 'POST':
            # 判断是否是确认页的提交(存在Yes/No参数)
            if 'Yes' in request.POST or 'No' in request.POST:
                curs = Cursuri.objects.get(id=object_id)
                # 获取隐藏字段传递的新名称
                new_name = request.POST.get('new_name')
                curs.titlu_curs = new_name
                curs.save()
                
                # 用户选择无关时,删除对应Note数据
                if 'No' in request.POST:
                    Note.objects.filter(id_curs=curs.id_curs).delete()
                
                # 跳转回课程列表页
                return HttpResponseRedirect(reverse('admin:vizualizare_cursuri_changelist'))
            
            # 处理第一次修改表单的提交
            else:
                new_name = request.POST.get('titlu_curs')
                curs = Cursuri.objects.get(id=object_id)
                old_name = curs.titlu_curs
                id_curs = curs.id_curs
                
                if new_name != old_name:
                    # 传递必要数据到确认页
                    extra_context = extra_context or {}
                    extra_context.update({
                        'new_name': new_name,
                        'old_name': old_name,
                        'id_curs': id_curs,
                        'object_id': object_id,
                    })
                    return render(request, 'vizualizare/confirmare_subiect.html', extra_context)
        
        # 非POST请求或无需确认时,调用父类默认逻辑
        return super().change_view(request, object_id, form_url, extra_context)

2. 修改确认页面模板

{% extends 'base.html' %}

{% block content %}
    <form action="{% url 'admin:vizualizare_cursuri_change' object_id %}" method="POST">
        {% csrf_token %}
        <!-- 隐藏字段传递必要数据 -->
        <input type="hidden" name="new_name" value="{{ new_name }}">
        <input type="hidden" name="old_name" value="{{ old_name }}">
        <input type="hidden" name="id_curs" value="{{ id_curs }}">
        
        <h2>新课程名称 "{{ new_name }}" 和旧名称 "{{ old_name }}" 是否相关?</h2>
        <input type="submit" value="是,两者相关" name="Yes"/>
        <input type="submit" value="否,两者无关" name="No"/>
    </form>
{% endblock %}

关键修复点说明

  • 强制数据库同步:修改titlu_curs后必须调用.save(),确保变更写入数据库。
  • 动态生成表单路径:使用{% url %}标签生成正确的Admin修改页路径,避免硬编码导致的跳转错误。
  • 参数安全传递:通过隐藏字段传递新名称、旧名称等数据,确保确认页提交时能正确获取上下文信息。
  • 分支逻辑区分:明确区分第一次修改提交和确认页提交的处理逻辑,根据用户选择执行对应操作:选择"Yes"仅保存新名称;选择"No"保存新名称并删除对应id_curs的所有Note数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 18:23:09