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"。
修复步骤
- 移除错误的action配置:删掉
actions = [save_model]这一行,save_model会在用户点击保存时自动触发,不需要加入actions列表。 - 修复正常保存逻辑:原代码中没有上传文件时,没有调用父类的
save_model方法,导致普通的单对象保存功能失效,需要在else分支补充父类方法调用。 - 补全缺失模型字段:代码中处理了
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
相关产品推荐
相关产品推荐

