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

Django Admin上传Excel导入数据库遇No reverse match错误求助

Django Admin导入Excel时出现"No reverse match error"

我是Django初学者,想通过Admin面板上传Excel文件,把Excel数据和Admin表单里填写的自定义字段结合后插入数据库。现在已经能组装好完整的数据对象,但插入时触发了No reverse match error。

注意:操作都在Admin面板里,没创建额外视图或配置URL,参考的示例也没额外配置,以下是我的实现代码,求帮忙解决!


代码实现

models.py

from django.db import models
from django.urls import reverse

class tblform(models.Model):
    
    ALSName = models.CharField(max_length=100)
    Study = models.CharField(max_length=100)
   
    FormId = models.CharField(max_length=100,primary_key=True)
    DraftName = models.CharField(max_length=100)
    OID=models.CharField(max_length=100)
    Ordinal = models.IntegerField(blank=True,null=True)
    DraftFormName = models.CharField(max_length=100)
    DraftFormActive = models.BooleanField(default=False)
    HelpText = models.CharField(max_length=100,blank=True,null=True)
    IsTemplate = models.BooleanField(default=False)

forms.py

from django import forms
from .models import tblform

class tblform_Form(forms.ModelForm):
    excel_file = forms.FileField(required=False)

    class Meta:
        model = tblform
        fields = ('ALSName','Study','DraftName')

admin.py

from django.contrib import admin
from .models import  tblform
from .forms1 import tblform_Form
import openpyxl

class ProductAdmin(admin.ModelAdmin):
    form = tblform_Form

    def save_model(self, request, obj, form, change):
        if 'excel_file' in request.FILES:
            excel_file = request.FILES['excel_file']
            field_names = [field.name for field in tblform._meta.get_fields() if field.name not in ['Study', 'DraftName','ALSName','tblfield','FormId']]
            Study = form.cleaned_data.get('Study')
            ALSName = form.cleaned_data.get('ALSName')
            DraftName = form.cleaned_data.get('DraftName')
            workbook = openpyxl.load_workbook(excel_file)
            worksheet = workbook['Forms1']

            for row in worksheet.iter_rows(min_row=2, values_only=True):

                field_values = dict(zip(field_names, row))
                if field_values['DraftFormActive'] == "TRUE":
                    field_values['DraftFormActive'] = True
                else:
                    field_values['DraftFormActive'] = False
                if field_values['IsTemplate']=="TRUE":
                    field_values['IsTemplate']=True
                else:
                    field_values['IsTemplate']=False

                if field_values['IsSignatureRequired']=="TRUE":
                    field_values['IsSignatureRequired']=True
                else:
                    field_values['IsSignatureRequired']=False

                if field_values['IsEproForm']=="TRUE":
                    field_values['IsEproForm']=True
                else:
                    field_values['IsEproForm']=False
                FormId = str(ALSName) + str(field_values['OID'])
               
                field_values.update({'FormId': FormId, 'Study': Study, 'ALSName': ALSName, 'DraftName': DraftName})
           
                tblform.objects.create(**field_values)
       
            self.message_user(request, "Data imported successfully.")

        else:
            self.message_user(request, "Invalid form data. Please check the form fields.")
            
    save_model.short_description = "Import data "
    actions = [save_model]

admin.site.register(tblform, ProductAdmin)

问题分析与修复方案

核心错误原因

save_model是Django Admin内置的单对象保存钩子方法,你错误地把它加入了actions列表中。Admin的actions是用于批量操作的,Django会尝试为每个action生成对应的URL路由,但save_model并不是标准的action方法,因此会触发"No reverse match error"。

修复步骤

  1. 移除错误的action配置:删掉actions = [save_model]这一行,save_model会在用户点击保存时自动触发,不需要加入actions列表。
  2. 修复正常保存逻辑:原代码中没有上传文件时,没有调用父类的save_model方法,导致普通的单对象保存功能失效,需要在else分支补充父类方法调用。
  3. 补全缺失模型字段:代码中处理了IsSignatureRequired和IsEproForm两个布尔字段,但模型中没有定义,会导致创建对象时抛出字段不存在的错误,需要在模型中补充这两个字段。

修正后的关键代码

修正后的models.py(补全字段)
from django.db import models

class tblform(models.Model):
    ALSName = models.CharField(max_length=100)
    Study = models.CharField(max_length=100)
    FormId = models.CharField(max_length=100, primary_key=True)
    DraftName = models.CharField(max_length=100)
    OID = models.CharField(max_length=100)
    Ordinal = models.IntegerField(blank=True, null=True)
    DraftFormName = models.CharField(max_length=100)
    DraftFormActive = models.BooleanField(default=False)
    HelpText = models.CharField(max_length=100, blank=True, null=True)
    IsTemplate = models.BooleanField(default=False)
    # 补全代码中用到的缺失字段
    IsSignatureRequired = models.BooleanField(default=False)
    IsEproForm = models.BooleanField(default=False)
修正后的admin.py
from django.contrib import admin
from .models import tblform
from .forms import tblform_Form  # 注意:如果你的表单文件是forms1.py则保留原导入,否则改为forms.py
import openpyxl

class ProductAdmin(admin.ModelAdmin):
    form = tblform_Form

    def save_model(self, request, obj, form, change):
        if 'excel_file' in request.FILES:
            excel_file = request.FILES['excel_file']
            # 去掉不存在的'tblfield'字段过滤
            field_names = [field.name for field in tblform._meta.get_fields() if field.name not in ['Study', 'DraftName','ALSName','FormId']]
            Study = form.cleaned_data.get('Study')
            ALSName = form.cleaned_data.get('ALSName')
            DraftName = form.cleaned_data.get('DraftName')
            workbook = openpyxl.load_workbook(excel_file)
            worksheet = workbook['Forms1']

            for row in worksheet.iter_rows(min_row=2, values_only=True):
                field_values = dict(zip(field_names, row))
                # 简化布尔值转换逻辑,避免重复代码
                for bool_field in ['DraftFormActive', 'IsTemplate', 'IsSignatureRequired', 'IsEproForm']:
                    field_values[bool_field] = field_values.get(bool_field) == "TRUE"
                
                FormId = f"{ALSName}{field_values['OID']}"
                field_values.update({
                    'FormId': FormId, 
                    'Study': Study, 
                    'ALSName': ALSName, 
                    'DraftName': DraftName
                })
                tblform.objects.create(**field_values)
           
            self.message_user(request, "数据导入成功。")
        else:
            # 调用父类方法,保证普通保存功能正常
            super().save_model(request, obj, form, change)
            self.message_user(request, "对象保存成功。")

admin.site.register(tblform, ProductAdmin)

额外注意事项

  • 检查表单文件导入路径:如果你的表单文件是forms.py,请把admin中的from .forms1 import tblform_Form改为from .forms import tblform_Form。
  • 确保Excel列顺序与field_names顺序完全一致,否则会出现字段值对应错误。
  • 主键FormId需要保证唯一性,可考虑添加重复校验或异常处理逻辑,避免导入失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 16:05:32