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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 04:35:23