Django如何获取指定商品已反馈用户列表 实现单用户单商品单次评价
解决方案
提取特定商品已反馈用户列表
你现有模型已经通过外键建立了商品、反馈、用户三者的关联,直接通过商品的反向关联即可拿到所有反馈记录,再提取对应用户即可。
修改views.py中的quick_view视图,补充查询逻辑:
def quick_view(request, quick_view_id): quick_view = get_object_or_404(Products, pk=quick_view_id) AllProductFeedback = quick_view.productREVIEWrelatedNAME.all() TotalProductsFeedback = AllProductFeedback.count() # 提取当前商品所有已反馈用户的ID集合,查询性能更高 reviewed_user_ids = set(AllProductFeedback.values_list('user_id', flat=True)) # 判断当前登录用户是否已提交过该商品反馈 has_user_submitted = request.user.is_authenticated and request.user.id in reviewed_user_ids context = { "quick_view": quick_view, "TotalProductsFeedback": TotalProductsFeedback, "AllProductFeedback": AllProductFeedback, "reviewed_user_ids": reviewed_user_ids, "has_user_submitted": has_user_submitted, } return render(request, 'quickVIEW_item.html', context)
其中reviewed_user_ids就是该商品所有已提交反馈的用户ID集合,如果需要拿到完整用户对象,直接遍历AllProductFeedback取user属性即可。
从根源限制单用户单商品仅能提交1条反馈
仅靠前端隐藏表单无法完全拦住重复提交,必须在模型层加联合唯一约束,从数据库层面阻断重复数据写入。
修改ProductREVIEWS模型,添加内部类Meta配置唯一约束:
class ProductREVIEWS(models.Model): user = models.ForeignKey(User, related_name='userREVIEW',on_delete=models.CASCADE) product = models.ForeignKey(Products, related_name='productREVIEWrelatedNAME',on_delete=models.CASCADE) class Meta: # 同一个用户+同一个商品的组合只能存在一条反馈记录 constraints = [ models.UniqueConstraint(fields=['user', 'product'], name='unique_review_per_user_per_product') ] def __str__(self): return str(self.pk) + "." + str(self.product) + "(" + str(self.user) + ")"
注意:你当前
Products模型里有一行冗余的错误代码on_delete=models.CASCADE, blank=True, null=True),直接删掉即可,否则执行迁移会报错。
修改完模型后依次执行以下命令让约束生效:
python manage.py makemigrations python manage.py migrate
前端控制表单显隐
在模板文件quickVIEW_item.html中,通过传入的has_user_submitted变量判断是否渲染反馈表单:
{% if request.user.is_authenticated and not has_user_submitted %} <!-- 未提交过反馈的登录用户可见表单 --> <form method="POST" action="/your-submit-review-endpoint/"> {% csrf_token %} <input type="hidden" name="product_id" value="{{ quick_view.pk }}"> <!-- 其他反馈字段,比如评分、评价内容 --> <button type="submit">提交反馈</button> </form> {% elif has_user_submitted %} <p>你已提交过该商品的反馈,无法重复提交</p> {% else %} <p>请登录后提交反馈</p> {% endif %}
提交接口增加校验
在处理反馈提交的视图逻辑中,也要增加重复提交校验,避免用户绕过前端直接调用接口提交重复数据:
from django.http import HttpResponseForbidden def submit_product_review(request): if request.method != "POST": return HttpResponseForbidden("请求方式不允许") product_id = request.POST.get("product_id") product = get_object_or_404(Products, pk=product_id) # 校验是否已提交过反馈 if ProductREVIEWS.objects.filter(user=request.user, product=product).exists(): return HttpResponseForbidden("你已提交过该商品的反馈,无法重复提交") # 正常保存反馈的逻辑 # review = ProductREVIEWS(user=request.user, product=product, ...) # review.save() # 跳转回商品页 return redirect(f"/product/{product_id}/")
内容的提问来源于stack exchange,提问作者Mossaddak
相关产品推荐
相关产品推荐

