button与a href的区别及Django中a href跳转失败的解决问询
Django中标签URL反转失败问题:原因分析与解决方案
一、先搞懂
这俩东西的本质完全不一样:
<button>是表单交互控件:如果它放在<form>标签里,默认点击会提交整个表单,参数是通过表单的字段(包括隐藏字段)传递给后端的。你的button能正常工作,大概率是它所在的表单已经偷偷把正确的pk(也就是账本的ID)通过隐藏字段或者表单的action URL传过去了,不需要在button本身写参数。<a>是超链接:它是直接在页面渲染的时候就生成一个完整的URL,所有需要的参数必须在模板渲染时就明确提供,完全依赖模板上下文里的变量,没法蹭表单的参数。
二、为什么你的标签版本会报错?
看错误提示:Reverse for 'create' with arguments '('',)' not found,翻译过来就是——你调用{% url 'moneylogs:create' pk %}的时候,pk这个变量是空的!
再结合你的代码细节:
- 你的
moneylogs:createURL需要的是账本(Moneybook)的pk,用来把新创建的流水关联到这个账本上(看你视图里self.kwargs["pk"]取的就是URL里的pk,然后查对应的Moneybook)。 - 你说尝试
pk=moneylog.pk也不行,那要么是模板里根本没有moneylog这个对象(毕竟是创建流水,当前页面可能还没有moneylog),要么是你传错了参数——应该传账本的pk,而不是流水的pk。
三、修复步骤,让标签正常工作
1. 先确认模板上下文里的正确变量
首先,你需要在渲染这个模板的视图里,把对应的moneybook对象(或者它的pk)传到模板里。比如如果这个按钮是在账本详情页,那渲染详情页的视图肯定已经把moneybook变量放到上下文里了,这时候你应该用moneybook.pk而不是pk或者moneylog.pk。
2. 修正标签的写法
直接把样式加到<a>标签上(别用
嵌套,语义更规范):
<a href="{% url 'moneylogs:create' moneybook.pk %}" class="px-2 py-1 rounded bg-red-500 text-white"> {{cta}} </a>
3. 额外修正:你的删除URL配置有问题
注意到你删除路径写的是:
path("<int:moneybook.pk>/delete/<int:moneylog.pk>", views.moneylog_delete, name="delete"),
Django的URL参数名不能包含.,这会导致视图里拿不到参数,改成:
path("<int:moneybook_pk>/delete/<int:moneylog_pk>", views.moneylog_delete, name="delete"),
然后在视图里用self.kwargs["moneybook_pk"]和self.kwargs["moneylog_pk"]来获取参数。
4. 验证变量是否存在
可以在模板里临时加一行打印,看看moneybook.pk有没有值:
<!-- 临时调试用,之后删掉 --> <p>当前账本ID:{{ moneybook.pk }}</p>
如果显示为空,那说明渲染这个模板的视图没有把moneybook传到上下文里,需要去对应的视图里加:
比如在类视图的get_context_data方法里添加:
def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context['moneybook'] = moneybook_models.Moneybook.objects.get(pk=self.kwargs["pk"]) return context
或者如果是函数视图,在render的时候传:
return render(request, '模板路径.html', {'moneybook': moneybook})
内容的提问来源于stack exchange,提问作者dhooonk
相关产品推荐
相关产品推荐

