如何处理Django Meta Class中的UniqueConstraint故障?

时间:2019-06-05 16:35:47

标签: python django

我为我的模型创建了UniqueConstraint元类,当我通过有意创建一个副本来对其进行测试时,它可以工作,但是我得到的是错误页面,而不是被重定向回原始页面。在哪里插入代码以返回到我所在的页面?

我认为问题出在视图中,但是我不知道要在其中放置什么代码,而Django文档中没有任何暗示此问题的东西。

型号:

class StudentScheduledClass(models.Model):
    student = models.ForeignKey("users.User", on_delete=models.CASCADE, db_column="Student")
    scheduled_class = models.ForeignKey("ScheduledClass", on_delete=models.CASCADE, db_column="ScheduledClass")
    grade = models.FloatField(db_column="Grade", blank=True, null=True)

    class Meta:
        managed = True
        db_table = "StudentScheduledClass"
        verbose_name_plural = "StudentsScheduledClasses"
        constraints = [
            models.UniqueConstraint(fields=['student', 'scheduled_class'], name='student scheduled class restraint')
        ]

查看:

class StudentScheduledClassCreateView(LoginRequiredMixin, CreateView):
    model = StudentScheduledClass
    context_object_name = "student_scheduled_class"
    fields = ["student"]

    def form_valid(self, form):
        scheduled_class = self.kwargs["scheduled_class"]
        form.instance.scheduled_class = ScheduledClass(scheduled_class)
        return super().form_valid(form)

    def get_success_url(self):
        scheduled_class = self.kwargs["scheduled_class"]
        return reverse("scheduled-class-detail", args={scheduled_class})

我只想返回一条错误消息返回原始页面,而是出现此完整性错误:

IntegrityError at /classes/student_scheduled_class_create/1/
UNIQUE constraint failed: StudentScheduledClass.Student, StudentScheduledClass.ScheduledClass
Request Method: POST
Request URL:    http://localhost:8000/classes/student_scheduled_class_create/1/
Django Version: 2.2.2
Exception Type: IntegrityError
Exception Value:    
UNIQUE constraint failed: StudentScheduledClass.Student, StudentScheduledClass.ScheduledClass

2 个答案:

答案 0 :(得分:1)

您的表单仅需要字段student,因此它是有效的,因为在验证后,您没有为其实例提供scheduled_class的值。

您应该使用已经设置了instance的{​​{1}}来初始化表单。您可以在scheduled_class中进行此操作,或者由于该方法将get_form_kwargs()作为self.object进行传递,因此可以在instance中进行以下操作:

post()

或者,虽然不太干净(我想认为一旦def post(self, request, *args, **kwargs): self.object = StudentScheduledClass(scheduled_class=kwargs['scheduled_class']) return super().post(request, *args, **kwargs) 被调用,一切都会好的):

form_valid()

最后一个问题是表单不会显示任何错误,因此您可能想在返回之前将Django消息添加到def form_valid(self, form): scheduled_class = self.kwargs["scheduled_class"] form.instance.scheduled_class = ScheduledClass(scheduled_class) try: return super().form_valid(form) except IntegrityError: return self.form_invalid(form) (假设您在自己的屏幕上显示了任何消息)模板)。

答案 1 :(得分:0)

这是我最终使用的代码:

查看:

class StudentScheduledClassCreateView(LoginRequiredMixin, CreateView):
    model = StudentScheduledClass
    context_object_name = "student_scheduled_class"
    fields = ["student"]

    def form_valid(self, form):
        try:
            scheduled_class = self.kwargs["scheduled_class"]
            form.instance.scheduled_class = ScheduledClass(scheduled_class)
            return super().form_valid(form)
        except IntegrityError as error:
            scheduled_class = self.kwargs["scheduled_class"]
            return self.form_invalid(form)

    def get_success_url(self):
        scheduled_class = self.kwargs["scheduled_class"]
        return reverse("scheduled-class-detail", args={scheduled_class})

模型保持不变:

class StudentScheduledClass(models.Model):
    student = models.ForeignKey("users.User", on_delete=models.CASCADE, db_column="Student")
    scheduled_class = models.ForeignKey("ScheduledClass", on_delete=models.CASCADE, db_column="ScheduledClass")
    grade = models.FloatField(db_column="Grade", blank=True, null=True)

    class Meta:
        managed = True
        db_table = "StudentScheduledClass"
        verbose_name_plural = "StudentsScheduledClasses"
        constraints = [
            models.UniqueConstraint(fields=['student', 'scheduled_class'], name='student scheduled class restraint')
        ]