如何在Django中实现房源收藏功能?
Django 收藏功能实现指南
基于你提供的Favorite模型和前端模板,下面是一套清晰的收藏功能实现步骤:
1. 后端视图实现
在你的app的views.py中添加处理收藏请求的视图,这里用函数视图实现状态切换逻辑:
from django.http import JsonResponse from django.contrib.auth.decorators import login_required from .models import Favorite, Apartment @login_required def toggle_favorite(request, apartment_id): apartment = Apartment.objects.get(id=apartment_id) # 切换收藏状态:存在则删除,不存在则创建 favorite, created = Favorite.objects.get_or_create(user=request.user, apartment=apartment) if not created: favorite.delete() return JsonResponse({ 'is_favorited': created, 'message': '已添加到收藏' if created else '已取消收藏' })
2. 配置URL路由
在app的urls.py中添加对应的路由:
from django.urls import path from . import views urlpatterns = [ # 其他已存在的URL... path('favorite/<int:apartment_id>/', views.toggle_favorite, name='toggle_favorite'), ]
3. 前端JS逻辑修改
在模板的{% block content %}末尾添加JavaScript代码,实现异步请求和按钮状态更新:
function addToFavorites(apartmentId) { fetch(`/favorite/${apartmentId}/`, { method: 'POST', headers: { 'X-CSRFToken': getCookie('csrftoken'), 'Content-Type': 'application/json' } }) .then(response => response.json()) .then(data => { const btn = event.target.closest('.btn'); const icon = btn.querySelector('i'); // 更新按钮样式与文本 if (data.is_favorited) { btn.classList.remove('btn-outline-secondary'); btn.classList.add('btn-danger'); btn.innerHTML = '<i class="fas fa-heart"></i> 已收藏'; } else { btn.classList.remove('btn-danger'); btn.classList.add('btn-outline-secondary'); btn.innerHTML = '<i class="fas fa-heart"></i> Add to Favorites'; } alert(data.message); }) .catch(error => console.error('操作失败:', error)); } // 获取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; }
4. 优化初始状态显示
让页面加载时就展示正确的收藏状态,需要修改列表视图和模板:
修改列表视图(如browse_rooms):
from django.contrib.auth.decorators import login_required from django.shortcuts import render @login_required def browse_rooms(request): apartments = Apartment.objects.all() # 获取当前用户已收藏的公寓ID集合 favorited_ids = request.user.favorite_set.values_list('apartment_id', flat=True) return render(request, 'browse_rooms.html', { 'apartments': apartments, 'favorited_ids': favorited_ids })
修改模板中的收藏按钮:
{% if apartment.id in favorited_ids %} <a href="#" class="btn btn-danger" onclick="addToFavorites({{ apartment.id }})"> <i class="fas fa-heart"></i> 已收藏 </a> {% else %} <a href="#" class="btn btn-outline-secondary" onclick="addToFavorites({{ apartment.id }})"> <i class="fas fa-heart"></i> Add to Favorites </a> {% endif %}
关键注意事项
- 所有收藏相关视图必须添加
@login_required,防止未登录用户操作 - 模型中的
unique_together已经保证了同一用户不会重复收藏同一公寓,get_or_create可以安全使用 - 前端POST请求必须携带CSRF令牌,否则会被Django的安全机制拦截
内容的提问来源于stack exchange,提问作者Spikyd
相关产品推荐
相关产品推荐

