如何通过点击按钮创建Django Favorite模型实例?
解决方案
1. 先确认Favorite模型的正确定义
首先确保你的Favorite模型设置唯一约束,避免同一用户重复收藏同一商品:
from django.db import models from django.contrib.auth.models import User from .models import Product # 假设Product在当前app的models模块中 class Favorite(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='favorites') product = models.ForeignKey(Product, on_delete=models.CASCADE, related_name='favorited_by') created_at = models.DateTimeField(auto_now_add=True) class Meta: # 确保同一用户不能重复收藏同一商品 unique_together = ('user', 'product')
2. 编写视图代码
函数视图版本
from django.shortcuts import get_object_or_404, redirect from django.contrib.auth.decorators import login_required from .models import Product, Favorite @login_required # 限制仅登录用户可操作 def add_to_favorite(request, product_id): product = get_object_or_404(Product, id=product_id) # 自动创建收藏,若已存在则跳过(避免报错) Favorite.objects.get_or_create(user=request.user, product=product) # 跳转回商品详情页 return redirect('product_details', product_id=product.id)
类视图版本(基于View)
from django.views import View from django.shortcuts import get_object_or_404, redirect from django.contrib.auth.mixins import LoginRequiredMixin from .models import Product, Favorite class AddToFavoriteView(LoginRequiredMixin, View): def get(self, request, product_id): product = get_object_or_404(Product, id=product_id) Favorite.objects.get_or_create(user=request.user, product=product) return redirect('product_details', product_id=product.id)
如果想用更规范的POST请求(避免GET请求的副作用),可以修改视图为处理POST:
# 函数视图适配POST的版本 @login_required def add_to_favorite(request, product_id): if request.method == 'POST': product = get_object_or_404(Product, id=product_id) Favorite.objects.get_or_create(user=request.user, product=product) return redirect('product_details', product_id=product.id) return redirect('product_details', product_id=product.id)
3. 配置URL规则
在app的urls.py中添加对应路由:
from django.urls import path from .views import add_to_favorite # 或导入AddToFavoriteView urlpatterns = [ # 其他已有URL... path('product/<int:product_id>/add-favorite/', add_to_favorite, name='add_to_favorite'), # 若用类视图则替换为: # path('product/<int:product_id>/add-favorite/', AddToFavoriteView.as_view(), name='add_to_favorite'), ]
4. 模板中的按钮设置
在product_details.html中添加「添加到收藏」按钮:
<!-- GET方式链接 --> <a href="{% url 'add_to_favorite' product.id %}" class="btn">添加到收藏</a> <!-- POST方式表单(更推荐) --> <form action="{% url 'add_to_favorite' product.id %}" method="post"> {% csrf_token %} <button type="submit" class="btn">添加到收藏</button> </form>
关键说明
@login_required/LoginRequiredMixin:强制用户登录后才能收藏,未登录用户会自动跳转到登录页(需提前配置LOGIN_URL)get_or_create:自动处理“已收藏则不重复创建”的逻辑,避免抛出重复记录异常- 模型的
unique_together:从数据层面保证不会出现重复收藏,和get_or_create配合双重保障
内容的提问来源于stack exchange,提问作者Sir.Breezy
相关产品推荐
相关产品推荐

