为什么模型实例没有提供给`DeleteView`内的`ModelForm`

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

使用 Django

5.0.2
,让我们从一个简单的模型开始:

from django.db import models


class Book(models.Model):
    title = models.CharField(max_length=100)

我想在

ModelForm
内进行一些表单验证,以确定是否应在
DeleteView
内进行删除。简而言之,我认为该表单已经能够显示非字段错误,并且我想避免使用
messages.error()
发回错误消息。

所以我从

ModelForm
开始:

from django.forms import ModelForm


class DeleteBookForm(ModelForm):
    class Meta:
        model = Book
        fields = []

    def clean(self):
        super().clean()
        if not self.deletable():
            self.add_error(None, 'This object can not be deleted')

    def deletable(self) -> bool:
        # do some evaluation on Book here
        book = self.instance
        if book.title == 'delete me please':
            return True
        else:
            return False

然后是

DeleteView

from django.views.generic import DeleteView
from django.http import HttpResponseRedirect


class DeleteBookView(DeleteView):
    model = Book
    form_class = DeleteBookForm

    def form_valid(self, form):
        self.object.delete()
        messages.success(self.request, 'The object has been deleted successfully.')
        return HttpResponseRedirect(self.get_success_url())

但是

self.instance
似乎是
None
DeleteBookForm.deletable()
里面。指示
Book
模型实例在创建时未提供/插入到
ModelForm
。我相信
UpdateView
情况并非如此。

花了一些时间阅读,我在

BaseDeleteView.post()
DeleteView
的父级)上找到了这段代码。请注意,它确实没有将对象插入到表单中:

class BaseDeleteView(DeletionMixin, FormMixin, BaseDetailView):
    def post(self, request, *args, **kwargs):
        self.object = self.get_object()
        form = self.get_form()
        if form.is_valid():
            return self.form_valid(form)
        else:
            return self.form_invalid(form)

最终,我所做的就是在创建表单时手动插入实例:

class DeleteBookView(DeleteView):
    def get_form(self, form_class=None):
        # insert instance so it can be read inside the form
        return self.form_class(
            instance=self.object,
            **self.get_form_kwargs()
        )

再次强调,模型实例是在

UpdateView
中默认提供的。

所以我的问题是:

  1. 为什么
    DeleteView
    默认不提供模型实例?
  2. ModelForm
    上使用
    DeleteView
    进行模型实例评估是错误的吗?我不确定,但我觉得 Form 是放置模型实例评估的最合乎逻辑的方式,而不是在 View 上。
python python-3.x django django-views django-forms
1个回答
0
投票

您只需要混合

ModelFormMixin
,即可将对象传递到表单:

from django.contrib.messages.views import SuccessMessageMixin
from django.views.generic.edit import ModelFormMixin


class DeleteBookView(SuccessMessageMixin, ModelFormMixin, DeleteView):
    model = Book
    form_class = DeleteBookForm
    success_message = 'The object has been deleted successfully.'
© www.soinside.com 2019 - 2024. All rights reserved.