使用 Django UpdateView 子类进行对象复制时处理无效数据

Handle invalid data when using Django UpdateView subclass for object duplication

我正在执行以下操作,当用户沿着黄金路径前进时效果很好:

class MyUpdate(UpdateView)
    # ...

class MyDuplicate(MyUpdate):
    def get_context_data(self, **kwargs):
        context = super(MyDuplicate, self).get_context_data(**kwargs)
        context['action'] = "Duplicate"
        return context

    # where should I call Klass::duplicate?

    def form_valid(self, form):
        name = form.instance.full_name
        video_url = form.instance.video_url

        # This doesn't work because it can result in unhandled uniqueness 
        # constraint violations.
        form.instance = Klass.duplicate(
            form.instance,
            name,
            video_url
        )
        return super(MyDuplicate, self).form_valid(form)

但是,如果用户尝试提交现有的 full_name(必须是唯一的),那么对 Klass.duplicate 的调用会导致未处理的唯一性约束冲突。

所以,我的问题是:在 UpdateView 生命周期中,我应该在哪里调用 Klass.duplicate(取消设置 pk,重置其他值,然后调用保存——为简洁起见省略)?

更新:

看起来覆盖 post 可能是一种方法。不幸的是,我不能只将表单实例传递给 Klass.duplicate,因为默认情况下它的字段是空的。

我想到的解决方案是通过 form_class 向 CBV 提供一个 ModelForm 子类,并使用其覆盖的 is_valid 方法来处理任何潜在的异常并向最终用户。

因此,根据我最初问题中的示例,解决方案如下所示:

class MyDuplicateForm(forms.ModelForm):
    class Meta:
        model = Klass
        fields = [...]

    def is_valid(self):
        valid = super(MyDuplicateForm, self).is_valid()
        if not valid:
            return False
        try:
            self.instance = Klass.duplicate(self.instance)
        except Exception as exception:
            self._errors[NON_FIELD_ERRORS] = exception
            return False

        return True

class MyDuplicate(UpdateView):
    form_class = MyDuplicateForm
    model = klass