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

Django中RateSugar表单实例赋值Sugargroup.seller问题排查

修复Django中RateSugarForm赋值错误及消费者权限限制问题

我来帮你解决这个问题,先拆解下你遇到的两个核心问题:属性不存在的错误和仅允许消费者提交表单的权限控制。

1. 错误根源解析

你碰到的'CheckoutDetail' object has no attribute 'relationto'错误,主要来自两个问题:

  • 方法名拼写错误:你定义了form_valide和form_invalide,但Django的FormMixin要求的正确方法名是form_valid和form_invalid,拼写错误会导致框架无法正确识别方法,调用父类方法时也会出错。
  • 错误的属性引用:self.relationto是你凭空定义的属性,CheckoutDetail类里根本没有这个字段。你想要关联的是当前的Sugargroup实例(也就是self.object),而rate_form.instance.sugar应该直接取self.object.seller(因为Sugargroup模型里有seller外键)。

2. 修正后的views.py代码

下面是修复后的完整代码,我标注了所有修改的关键点:

from django.http import HttpResponseForbidden

class CheckoutDetail(generic.DetailView, FormMixin):
    model = Sugargroup
    context_object_name = 'sugargroup'
    template_name = 'checkout_detail.html'
    form_class = CreateSugarChatForm
    rate_form_class = RateSugarForm

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['form'] = self.get_form()
        context['rate_form'] = self.get_form(self.rate_form_class)
        return context

    def form_valid(self, form):
        if form.is_valid():
            form.instance.sugargroup = self.object
            form.instance.user = self.request.user
            form.save()
            return super().form_valid(form)
        else:
            return super().form_invalid(form)

    # 修复方法名拼写错误:form_valide → form_valid
    def form_valid(self, rate_form):
        # 新增:仅允许当前Sugargroup的消费者提交评价
        if self.request.user != self.object.consumer:
            return HttpResponseForbidden("只有该订单的消费者可以提交评价")
        
        if rate_form.is_valid():
            # 修复属性引用:直接使用当前Sugargroup实例关联relationto
            rate_form.instance.relationto = self.object
            # 直接从Sugargroup实例中取seller赋值给sugar字段
            rate_form.instance.sugar = self.object.seller
            # 注意:Ratesugar模型里是user字段对应评价者(related_name为ratesugar_cooker)
            rate_form.instance.user = self.request.user
            rate_form.save()
            return super().form_valid(rate_form)
        else:
            # 修复方法名拼写:form_invalide → form_invalid
            return super().form_invalid(rate_form)

    def post(self, request, *args, **kwargs):
        self.object = self.get_object()
        form = self.get_form()
        rate_form = self.get_form(self.rate_form_class)
        
        # 优化表单提交判断:通过提交按钮的name区分两个表单
        if 'chat_submit' in request.POST and form.is_valid():
            return self.form_valid(form)
        elif 'rate_submit' in request.POST and rate_form.is_valid():
            return self.form_valid(rate_form)
        else:
            # 表单验证失败时返回错误上下文
            return self.form_invalid(form)

    def get_success_url(self):
        return reverse('checkout:checkout_detail', kwargs={"slug": self.object.slug})

3. 额外的注意事项

  • 表单提交按钮区分:建议给两个表单的提交按钮添加不同的name属性,比如聊天表单用<input type="submit" name="chat_submit">,评价表单用<input type="submit" name="rate_submit">,这样post方法里能准确判断用户提交的是哪个表单。
  • 模型字段一致性:你的Ratesugar模型里,评价者对应的字段是user(related_name='ratesugar_cooker'),原代码里写的rate_form.instance.cooker会报错,已经修正为rate_form.instance.user。

内容的提问来源于stack exchange,提问作者Louis

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 11:28:16