Django+HTMX实现可编辑行时出现NoReverseMatch错误求助
Django + HTMX 可编辑行触发NoReverseMatch错误
我用Django搭配HTMX实现链接列表的可编辑行功能,点击行内编辑按钮时出现django.urls.exceptions.NoReverseMatch错误,具体提示:
Reverse for 'link_update' with keyword arguments '{'pk': ''}' not found. 1 pattern(s) tried: ['link/edit/(?P[0-9]+)/\Z']
试过Stack Overflow上的多种方法仍未解决,相关代码如下:
项目根目录urls.py
urlpatterns = [ path('', home, name='home'), path('admin/', admin.site.urls), path("user/", include("user_profile.urls", namespace="user")), path("link/", include("link.urls", namespace='link')), ]
link应用下的urls.py
from django.urls import path from link.views import tag_view, category_view, delete_links, delete_link, get_row_view, LinkUpdateView, LinkyListView app_name = 'link' urlpatterns = [ path('edit/<int:pk>/', LinkUpdateView.as_view(), name='link_update'), path('edit/<int:pk>/get_row_view/', get_row_view, name='get_row_view'), path('tag/<slug:tag_slug>/', tag_view, name='tag_view'), path('category/<slug:category_slug>/', category_view, name='category_view'), path('delete/', delete_links, name='delete_links'), path('delete-item/<int:pk>/', delete_link, name='delete_link'), path('list', LinkyListView.as_view(), name='link_list_view'), ]
link应用下的views.py
def get_row_view(request, pk): link = LinkUrl.objects.get(pk=pk) context = dict( link=link, ) return render(request, 'link/row.html', context) class LinkUpdateView(UpdateView): model = LinkUrl form_class = LinkModelForm template_name = 'link/edit_link_form.html' def get_success_url(self): return reverse_lazy('link:link_update', kwargs={'pk': self.object.pk})
row.html
<tr id="link_list_{{link.pk}}"> <td>{{ link.title }}</td> <td>{{ link.get_full_url }}</td> <td> <span class="p-1 border fs-12 rounded text-light bg-primary"> <a href="{{ link.category.get_absolute_url }}" class="text-decoration-none text-light"> {{ link.category }} </a> </span> </td> <td> {% for shortcode, tags in tags_by_shortcode.items %} {% if shortcode == link.shortcode %} {% for tag in tags %} <li class="list-inline-item border p-1 text-muted fs-12 mb-1 rounded"> <a href="{{ tag.get_absolute_url }}" class="text-decoration-none text-muted"> {{ tag.title }} </a> </li> {% endfor %} {% endif %} {% endfor %} </td> <td> <button class="btn btn-warning" hx-get="{% url 'link:link_update' pk=link.pk %}" hx-target="#link_list_{{link.pk}}"> Edit </button> </td> <td> <button class="btn btn-danger btn-sm float-end" hx-delete="{% url 'link:delete_link' link.pk %}" hx-confirm="Are you sure you want to delete this item?" hx-target="#link_list_{{link.id}}" hx-swap="outerHTML"> Delete </button> </td> </tr>
edit_link_form.html
<td> <form hx-post="{% url 'link:link_update' pk=link.pk %}"> {% csrf_token %} {% load crispy_forms_tags %} {% for field in form %} <td colspan="{{ form|length }}"> <div class="form-row"> <div class="form-group col-md-12"> {{ field|as_crispy_field }} </div> </div> </td> {% endfor %} <td> <button class="btn btn-primary" type="submit" hx-get="{% url 'link:get_row_view' pk=link.pk %}" hx-target="#form-container"> Save </button> </td> <td> <button class="btn btn-danger" type="button">Cancel</button> </td> </form> </td>
问题排查与修复
错误核心是模板渲染时pk参数为空,导致URL反转失败,针对性修复如下:
- 修正EditForm的上下文变量
Django的UpdateView默认将当前对象以object或小写模型名(linkurl)传入上下文,而非link。所以edit_link_form.html里的link.pk取不到值,导致URL反转时pk为空。
- 方案一:把
edit_link_form.html中所有link.pk替换为object.pk - 方案二:在
LinkUpdateView中手动添加link到上下文:class LinkUpdateView(UpdateView): # 原有代码保留 def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context['link'] = self.object return context
- 调整保存后的跳转逻辑
当前get_success_url返回编辑页面本身,不符合HTMX交互逻辑,应该返回更新后的行HTML:
def get_success_url(self): return reverse_lazy('link:get_row_view', kwargs={'pk': self.object.pk})
同时修改edit_link_form.html的提交按钮,让HTMX直接替换目标行:
<button class="btn btn-primary" type="submit" hx-target="#link_list_{{object.pk}}" hx-swap="outerHTML"> Save </button>
- 统一模板中的ID引用
row.html里tr的ID是link_list_{{link.pk}},但删除按钮的hx-target用了link_list_{{link.id}},建议统一为link.pk避免潜在问题。
内容的提问来源于stack exchange,提问作者Hilal
相关产品推荐
相关产品推荐

