如何在Django中实现无需页面重载的关注/取消关注功能
实现Django无刷新关注/取消关注功能
要实现无需页面重载的关注状态切换,核心是用AJAX(Fetch API)发送异步请求,后端返回JSON响应,前端动态更新按钮状态。以下是具体修改步骤:
一、修改视图函数(views.py)
把原来返回重定向的follow和unfollow视图改成返回JSON,同时限定请求方式为POST:
from django.http import JsonResponse from django.views.decorators.http import require_POST from django.contrib.auth.decorators import login_required from .models import Photo, UserProfile # 保留原viewPhoto函数不变 @login_required @require_POST def follow(request, pk): photo = get_object_or_404(Photo, id=pk) user_profile, created = UserProfile.objects.get_or_create(user=request.user) user_profile.follows.add(photo) return JsonResponse({'success': True, 'is_following': True}) @login_required @require_POST def unfollow(request, pk): photo = get_object_or_404(Photo, id=pk) user_profile, created = UserProfile.objects.get_or_create(user=request.user) user_profile.follows.remove(photo) return JsonResponse({'success': True, 'is_following': False})
二、更新HTML模板
将原来的a标签替换为按钮,给容器添加data-photo-id属性方便JS获取照片ID:
<div class="btn follow" data-photo-id="{{ photo.id }}"> {% if is_following %} <button type="button" class="follow-btn">取消关注</button> {% else %} <button type="button" class="follow-btn">关注</button> {% endif %} </div>
三、添加JavaScript代码
在模板底部(比如</body>前)加入以下JS,实现异步请求和状态更新:
document.addEventListener('DOMContentLoaded', function() { const followContainers = document.querySelectorAll('.follow'); followContainers.forEach(container => { const btn = container.querySelector('.follow-btn'); const photoId = container.dataset.photoId; btn.addEventListener('click', async function() { const isFollowing = btn.textContent.trim() === '取消关注'; const url = isFollowing ? `/photo/${photoId}/unfollow/` : `/photo/${photoId}/follow/`; try { const response = await fetch(url, { method: 'POST', headers: { 'X-CSRFToken': getCookie('csrftoken'), 'Content-Type': 'application/json' } }); if (!response.ok) { if (response.status === 403) { alert('请先登录'); // 可选:跳转到登录页 // window.location.href = '/accounts/login/'; return; } throw new Error('请求失败'); } const data = await response.json(); if (data.success) { btn.textContent = data.is_following ? '取消关注' : '关注'; } else { alert('操作失败,请重试'); } } catch (error) { alert('网络错误,请稍后再试'); } }); }); }); // 获取Django CSRF令牌的工具函数 function getCookie(name) { let cookieValue = null; if (document.cookie && document.cookie !== '') { const cookies = document.cookie.split(';'); for (let i = 0; i < cookies.length; i++) { const cookie = cookies[i].trim(); if (cookie.substring(0, name.length + 1) === (name + '=')) { cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); break; } } } return cookieValue; }
四、额外优化(可选)
- 点击按钮时添加加载状态:比如在请求发送时禁用按钮,显示“加载中...”,请求完成后恢复。
- 给按钮添加样式变化,比如关注后按钮变色,更直观。
内容的提问来源于stack exchange,提问作者user22601065
相关产品推荐
相关产品推荐

