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

如何通过HTMX从事件获取数据?标签删除同步会话列表问题

问题与解决方案

问题背景

我有如下视图用于删除标签,运行正常:

def tag_delete(request):
    if request.method == 'POST':
        tag_name = request.POST.get("tag")
        tag = Tag.objects.get(name=tag_name)
        tag.delete()

        response = HttpResponse(status=204, headers={'HX-Trigger': json.dumps({
                "taglistchangeddelete": {"tag": tag_name}
            })})
                  
        return response

但需要同步移除会话变量selected_tags中的已删除标签,因此创建了处理视图:

def process_tags_deleted(request, tag):   

    selected_tags = request.session['selected_tags']    
    if tag in selected_tags:
        selected_tags.remove(tag)

    request.session['selected_tags'] = selected_tags
    
    # 渲染模板展示用户的选中标签
    response = render(request, 'espace/tags_selected.html', {
             'selected_tags': selected_tags,
          })  

    return response

在模板中用HTMX设置GET请求触发该视图时,控制台出现htmx:syntax:error,无法从taglistchangeddelete事件中获取tag值:

<div hx-get={% url 'process_tags_deleted' %}
         hx-vals='{"tag": evt.detail.tag}'
         hx-target="#tags_selected"
         hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
         hx-trigger="taglistchangeddelete">
    </div>

错误原因

htmx:syntax:error是因为**hx-vals的写法不符合HTMX语法规则**:直接在JSON字符串中写入JS变量evt.detail.tag,HTMX无法解析这种格式,必须使用HTMX支持的表达式写法。

修复方案

1. 修正hx-vals的写法

有两种合法的写法可以从事件中取值:

方式一:使用javascript:前缀执行JS表达式

<div hx-get="{% url 'process_tags_deleted' %}"
     hx-vals='javascript: {tag: evt.detail.tag}'
     hx-target="#tags_selected"
     hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
     hx-trigger="taglistchangeddelete">
</div>

方式二:使用HTMX模板语法包裹变量

<div hx-get="{% url 'process_tags_deleted' %}"
     hx-vals='{"tag": "{{ evt.detail.tag }}"}'
     hx-target="#tags_selected"
     hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
     hx-trigger="taglistchangeddelete">
</div>

2. 修正视图的参数接收逻辑

原视图将tag作为位置参数,但HTMX GET请求会把参数放在查询字符串中,需要修改视图从request.GET获取参数,同时增加异常处理避免KeyError:

def process_tags_deleted(request):   
    tag = request.GET.get("tag")
    if not tag:
        return HttpResponseBadRequest()
    
    # 确保会话中存在selected_tags,不存在则返回空列表
    selected_tags = request.session.get('selected_tags', [])
    if tag in selected_tags:
        selected_tags.remove(tag)

    request.session['selected_tags'] = selected_tags
    
    return render(request, 'espace/tags_selected.html', {
             'selected_tags': selected_tags,
          })  

3. 更新URL配置

去掉URL中的tag位置参数,示例如下:

# urls.py
from django.urls import path
from . import views

urlpatterns = [
    # ... 其他URL
    path('process-tags-deleted/', views.process_tags_deleted, name='process_tags_deleted'),
]

内容的提问来源于stack exchange,提问作者Isaac Fritsch

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 12:24:58