Обработка неверных данных при использовании подкласса Django UpdateView для дублирования объектов - PullRequest
0 голосов
/ 24 апреля 2019

Я делаю следующее, что хорошо работает, когда пользователь идет по золотому пути:

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 (сбросить pk, сбросить другие значения и затем вызвать save -- для краткости) в жизненном цикле UpdateView?

ОБНОВЛЕНИЕ:

Похоже, что переопределение post может быть одним из способов сделать это.К сожалению, я не могу просто передать экземпляр формы в Klass.duplicate, так как ее поля по умолчанию пусты.

1 Ответ

0 голосов
/ 26 апреля 2019

Решение, которое я придумал, состояло в том, чтобы предоставить подкласс 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
...