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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 17:06:28