Django 更新用户的费率

Django update the user's rate

我正在尝试实施用户只能对(例如这样的人)进行一次评价但可以更改其评价的评价系统。

class Rate(models.Model):

    class Meta:
        unique_together = (('sender', 'person'),)

    choice = models.IntegerField(null=False, blank=False, choices=RATE_CHOICES)
    sender = models.ForeignKey(User, on_delete=models.CASCADE)
    person = models.ForeignKey(Person, on_delete=models.CASCADE, null=True)

我发现了类似 unique_together 的东西并且它有效 - 用户只能评价一次,但我无法更改它。

def form_valid(self, form):
        vote, created = Rate.objects.get_or_create(
                        sender=self.request.user, 
                        person=self.get_object(),
                        choice=form.cleaned_data['choice'])
                    

        if not created:
            Rate.objects.filter(sender=self.request.user, person=self.get_object()).update(choice=form.cleaned_data['choice'])
            return super(PersonDetailView, self).form_valid(form)
        else:
            return super(PersonDetailView, self).form_valid(form)

我尝试了类似上面的方法,但仍然得到

UNIQUE constraint failed: main_rate.sender_id, main_rate.person_id

get_or_create(…) [Django-doc] 将尝试使用给定的过滤器检索项目,如果找不到,则构造一个新的。问题在于,您在 senderpersonchoice 上进行过滤,因此如果 choice 不同与已经保存的相比,它将尝试构建一个新的 Rate,因此数据库将拒绝它。

您可以使用 update_or_create(…) [Django-doc],从而在 defaults=… 参数中指定 choice

def form_valid(self, form):
    Rate.objects<b>.update_or_create(</b>
        sender=self.request.user, 
        person=self.object,
        <b>defaults={</b>'choice': form.cleaned_data['choice']<b>}</b>
    <b>)</b>
    return super().form_valid(form)

但是请注意,super().form_valid(form) 将尝试保存表格。因此,简单地 return 重定向到成功可能更好 url:

from django.http import <b>HttpResponseRedirect</b>

class MyView(…):
    
    def form_valid(self, form):
        Rate.objects.update_or_create(
            sender=self.request.user, 
            person=self.object,
            defaults={'choice': form.cleaned_data['choice']}
        )
        return <b>HttpResponseRedirect(self.get_success_url())</b>