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

button与a href的区别及Django中a href跳转失败的解决问询

一、先搞懂

这俩东西的本质完全不一样:

  • <button>是表单交互控件:如果它放在<form>标签里,默认点击会提交整个表单,参数是通过表单的字段(包括隐藏字段)传递给后端的。你的button能正常工作,大概率是它所在的表单已经偷偷把正确的pk(也就是账本的ID)通过隐藏字段或者表单的action URL传过去了,不需要在button本身写参数。
  • <a>是超链接:它是直接在页面渲染的时候就生成一个完整的URL,所有需要的参数必须在模板渲染时就明确提供,完全依赖模板上下文里的变量,没法蹭表单的参数。

二、为什么你的标签版本会报错?

看错误提示:Reverse for 'create' with arguments '('',)' not found,翻译过来就是——你调用{% url 'moneylogs:create' pk %}的时候,pk这个变量是空的!

再结合你的代码细节:

  1. 你的moneylogs:create URL需要的是账本(Moneybook)的pk,用来把新创建的流水关联到这个账本上(看你视图里self.kwargs["pk"]取的就是URL里的pk,然后查对应的Moneybook)。
  2. 你说尝试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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 12:07:40