窗体的干净方法没有被调用

Form's clean method not getting called

我正在尝试使用 Django 的 CBV 创建一些对象 FormView form_class 的代码是这样的:

class UrlForm(forms.Form):
    url = forms.CharField(required=True,
                help_text=_("This should be an absolute path, excluding the domain name.\
                             Example: '/events/search/'."),
                widget=forms.TextInput(attrs={'style':'width:400px;'}))
    title = forms.CharField(required=True, widget=forms.Textarea())
    description = forms.CharField(required=True, widget=forms.Textarea())
    keywords = forms.CharField(required=True, widget=forms.Textarea())

    def clean(self):
        cleaned_data = super(UrlForm, self).clean()
        url = cleaned_data.get('url')
        try:
            Url.objects.get(url=url)
            raise forms.ValidationError("Seo Url already exists.")
        except:
            pass
        return cleaned_data

并且我使用此视图来呈现表单:

class CreateSeoByUrl(FormView):
    template_name = 'create_seo_by_url.html'
    form_class = UrlForm

    def get_success_url(self):
        return reverse('dashboard:index')

    def post(self, request, *args, **kwargs):
        url = Url.objects.create(url= request.POST.get('url'))
        seo = Seo.objects.create(
                    title = request.POST.get('title'),
                    description = request.POST.get('description'),
                    keywords = request.POST.get('keywords'),
                    content_object=url)

        return redirect(self.get_success_url())

url 应该是唯一的,所以我尝试提高 ValidationError 如果存在 Url 具有相同的 value.But 问题是,它不会进入表格clean 方法也不在 form_validform_invalid 中,它只是简单地跳转到 post 方法并尝试创建 url 和 seo 对象。为什么我的表单的 clean 方法 /form_valid/invalid 没有被调用..我束手无策!

调用 clean 时,您必须 return 使用 self

清理数据
def clean(self):
    url = self.cleaned_data.get('url')
    try:
        my_url = Url.objects.get(url=url)
        if my_url:
            raise forms.ValidationError("Seo Url already exists.")
    except Url.DoesNotExist:
        pass
    return self.cleaned_data

这将不起作用,因为您正在覆盖视图中的整个 post 方法。该 post 方法默认负责调用表单验证,然后调用 form_validform_invalid 方法。

如果您根本不使用表单,那么使用 FormView 有什么意义。

另外:您应该引用表单的 cleaned_data 而不是 request.POST。它将只包含完全清理过的数据。

你的post方法是错误的。您必须使用如下所示的 form_valid 方法

def form_valid(self, form):
    url = Url.objects.create(url= form.cleaned_data['url'])
    seo = Seo.objects.create(
                title = form.cleaned_data['title'],
                description = form.cleaned_data['description'],
                keywords = form.cleaned_data['keywords'],
                content_object=url)

    return redirect(self.get_success_url())

或者如果您想使用 Post 方法,请按如下方式使用:

def post(self, request, *args, **kwargs):
    form = self.form_class(request.POST)
    if form.is_valid():
        url = Url.objects.create(url= form.cleaned_data['url'])
        seo = Seo.objects.create(
                title = form.cleaned_data['title'],
                description = form.cleaned_data['description'],
                keywords = form.cleaned_data['keywords'],
                content_object=url)

    return redirect(self.get_success_url())

我已经对代码进行了测试,但它会起作用。让我解释一下为什么您的代码不起作用。在您的 post 方法中,您没有使用 post 参数初始化表单。表单初始化后,您可以 运行 clean 方法,它会引发异常(如果有)。此外,由于您使用的是 FormView,因此有一个 form_valid 方法(我的建议是在开发之前先阅读)。另一个建议,既然你正在使用表单创建对象,为什么不使用 CreateView 和 ModelForm..:)