Django视图点击后切换按钮异常:HTMX实现问题求助
问题修复方案
当前无法切换按钮状态的核心问题有三点:表单未配置正确的HTMX交换规则、视图返回内容不符合前端处理需求、JS监听逻辑存在错误。以下是具体修复步骤:
方案一:使用JS手动更新按钮(适合需要额外逻辑的场景)
1. 修正表单的HTMX属性
添加hx-swap="none"阻止HTMX自动替换内容,让JS接管更新逻辑:
<form id="follow-form" hx-post="{% url 'main:follow_toggle' account.id %}" hx-swap="none"> {% csrf_token %} {% if request.user in account.followers.all %} <button type="submit" id="follow-button" class="btn btn-secondary rounded-pill">עוקב</button> {% else %} <button type="submit" id="follow-button" class="btn btn-success rounded-pill">עקוב</button> {% endif %} </form>
2. 修改Django视图返回JSON状态
替换纯文本响应为JSON,返回当前关注状态:
from django.http import JsonResponse from django.views import generic from .models import Account class FollowToggleView(generic.View): def post(self, request, account_id): user_to_toggle = get_object_or_404(Account, id=account_id) is_following = user_to_toggle in request.user.following.all() if is_following: request.user.unfollow(user_to_toggle) is_following = False else: request.user.follow(user_to_toggle) is_following = True return JsonResponse({'is_following': is_following})
3. 修复JS监听逻辑
修正目标ID,正确解析JSON响应:
<script> const followButton = document.getElementById('follow-button'); document.addEventListener('htmx:afterRequest', (event) => { if (event.detail.target.id === 'follow-form') { const response = JSON.parse(event.detail.xhr.responseText); if (response.is_following) { followButton.innerText = 'עוקב'; followButton.classList.remove('btn-success'); followButton.classList.add('btn-secondary'); } else { followButton.innerText = 'עקוב'; followButton.classList.remove('btn-secondary'); followButton.classList.add('btn-success'); } } }); </script>
方案二:用HTMX自动替换按钮(更符合HTMX极简理念)
1. 创建按钮局部模板
新建partials/follow_button.html文件:
<button type="submit" id="follow-button" class="btn {% if is_following %}btn-secondary{% else %}btn-success{% endif %} rounded-pill"> {% if is_following %}עוקב{% else %}עקוב{% endif %} </button>
2. 修改视图返回按钮HTML片段
from django.shortcuts import render from django.views import generic from .models import Account class FollowToggleView(generic.View): def post(self, request, account_id): user_to_toggle = get_object_or_404(Account, id=account_id) is_following = user_to_toggle in request.user.following.all() if is_following: request.user.unfollow(user_to_toggle) is_following = False else: request.user.follow(user_to_toggle) is_following = True return render(request, 'partials/follow_button.html', { 'is_following': is_following })
3. 配置表单的HTMX替换规则
让HTMX直接替换按钮元素:
<form id="follow-form" hx-post="{% url 'main:follow_toggle' account.id %}" hx-target="#follow-button" hx-swap="outerHTML"> {% csrf_token %} {% if request.user in account.followers.all %} <button type="submit" id="follow-button" class="btn btn-secondary rounded-pill">עוקב</button> {% else %} <button type="submit" id="follow-button" class="btn btn-success rounded-pill">עקוב</button> {% endif %} </form>
内容的提问来源于stack exchange,提问作者Killer
相关产品推荐
相关产品推荐

