Django中'edit-item'反向解析失败及商品编辑删除功能异常排查求助
先直接点出问题根源:你看到的这个错误,本质是调用reverse生成edit-item URL时,传入的slug参数是空字符串,而你的URL规则要求slug必须是至少一个非斜杠字符的内容([^/]+),所以匹配失败。接下来我们一步步把问题修好:
1. 先解决slug为空的核心问题
首先检查你的Furniture模型实例,肯定有部分商品的slug字段是空的。虽然SlugField默认不允许空值,但可能你之前创建商品时没有自动生成slug的逻辑,导致某些数据漏了。
给模型添加自动生成slug的逻辑,确保每个商品都有唯一的slug:
from django.utils.text import slugify class Furniture(models.Model): furnitureId = models.CharField(primary_key=True, max_length=50) furnitureName = models.CharField(max_length=50) unitPrice = models.DecimalField(max_digits=8, decimal_places=2) categoryId = models.ForeignKey(Category, on_delete=models.CASCADE) slug = models.SlugField(max_length=100, unique=True) # 加上unique避免重复 def save(self, *args, **kwargs): # 如果slug为空,自动从商品名+ID生成 if not self.slug: self.slug = slugify(f"{self.furnitureName}-{self.furnitureId}") super().save(*args, **kwargs) def get_absolute_url(self): return reverse("administration:edit-item", kwargs={ 'slug': self.slug }) def delete_item_url(self): return reverse("administration:delete-item", kwargs={ 'slug': self.slug })
这样以后新增商品时,slug会自动生成,不会再出现空值。
2. 修复视图函数的参数不匹配
你的urls.py里edit-item的URL是path('edit-item/<slug>/',views.editProduct, name='edit-item'),这里的URL参数名是slug,但你的views.py里editProduct函数却用了fid当参数名:
def editProduct(request, fid): item = get_object_or_404(Furniture, slug=fid)
这会导致Django无法正确传递URL里的slug值,把参数名改成slug就好了:
def editProduct(request, slug): item = get_object_or_404(Furniture, slug=slug) category = Category.objects.all() context = { 'object':item, 'category':category } return render(request, 'admin/item.html', context)
3. 修正模板里的删除链接
你模板里删除链接直接写{{ object.slug }},这会生成相对路径(比如当前在/dashboard/products/,链接会变成/dashboard/products/xxx),但正确的删除URL应该是/dashboard/delete-item/xxx,所以直接用模型里定义的delete_item_url()方法:
{% for object in furniture %} <tr class="clickable-tr" href="{{ object.get_absolute_url }}"> <td>{{ object.furnitureId }}</td> <td>{{ object.furnitureName }}</td> <td>{{ object.categoryId.categoryName }}</td> <td class="text-center">{{ object.stock }}</td> <td class="text-center"> <a href="{{ object.delete_item_url }}"> <i class='material-icons' style="color: brown;">delete</i> </a> </td> </tr> {% endfor %}
4. 批量修复现有数据的空slug
如果你的数据库里已经有slug为空的商品,用Django Shell批量处理:
python manage.py shell
然后执行:
from django.utils.text import slugify from your_app.models import Furniture # 替换成你的应用名 for item in Furniture.objects.filter(slug__exact=''): item.slug = slugify(f"{item.furnitureName}-{item.furnitureId}") item.save()
做完这些步骤,你的编辑和删除功能应该就能正常工作了。
内容的提问来源于stack exchange,提问作者HSan

