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

问题描述 投票:0回答:1

我正在做以下操作,当用户沿着黄金路径行进时,它可以很好地工作:

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的调用会导致未处理的唯一性约束违规。

所以,我的问题是:在Klass.duplicate生命周期中,我应该在哪里调用UpdateView(unsets pk,重置其他值,然后调用save - 为简洁而省略)?

更新:

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

django python-2.7 django-class-based-views django-1.11
1个回答
0
投票

我想出的解决方案是通过ModelForm向CBV提供form_class子类,并使用其重写的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
© www.soinside.com 2019 - 2024. All rights reserved.