Django 清除方法不适用于URL字段

Django 清除方法不适用于URL字段,django,Django,我正在做一些需要用户输入URL的事情。然后我意识到,大多数用户在编写URL时都不会在“http://”前面加前缀,于是我决定使用干净的方法。在检查了很多地方的URLField清理方法后,我提出了以下建议: from django import forms from rango.models import Category, Page class CategoryForm(forms.ModelForm): name = forms.CharField(max_length=128, h

我正在做一些需要用户输入URL的事情。然后我意识到,大多数用户在编写URL时都不会在“http://”前面加前缀,于是我决定使用干净的方法。在检查了很多地方的URLField清理方法后,我提出了以下建议:

from django import forms
from rango.models import Category, Page

class CategoryForm(forms.ModelForm):
    name = forms.CharField(max_length=128, help_text="Please enter category name")
    views = forms.IntegerField(widget=forms.HiddenInput(), initial=0)
    likes = forms.IntegerField(widget=forms.HiddenInput(), initial=0)
    slug = forms.CharField(widget=forms.HiddenInput(), required=False)

    # Create an inline class to provide extra information about the form
    class Meta:
        # Provide the association between a model form and a model
        model = Category
        fields = ('name',)

class PageForm(forms.ModelForm):
    title = forms.CharField(max_length=128, help_text="Please enter the title of the page")
    url = forms.URLField(max_length=200, help_text="Please enter the url of the page", initial="http://")
    views = forms.IntegerField(widget=forms.HiddenInput(), initial=0)

    def clean(self):
        cleaned_data = self.cleaned_data
        url = cleaned_data.get('url')

        # If url is not empty and doesn't start with http://, prepend it
        if url and not url.startswith('http://'):
            url = 'http://' + url
            cleaned_data['url'] = url

            return cleaned_data

    class Meta:
        # Provide association between model form and model
        model = Page
        # What fields do we want to include or exclude from our form?
        exclude = ('category',)

不幸的是,这不起作用,因为我仍然得到无效的url错误。有什么我遗漏的吗?如果是,什么?

因为您只验证一个字段,所以不应该在forms clean方法中进行验证,而应该在
clean\u url
-方法中进行验证。对我来说,这很有效:

class PageForm(forms.ModelForm):
    def clean_url(self):
        url = self.cleaned_data.get('url')
        if not url.startswith('http://'):
            url = 'http://' + url
        return url

如果您没有为URL输入方案(例如
http://
),Django将默认为
http://
。因此,您不需要
clean_url
方法,可以将其删除

问题在于,由于Django使用
type=url
呈现表单,因此浏览器也在验证输入。因为浏览器认为输入无效,所以表单永远不会提交给Django

一个选项是将输入更改为
TextInput
,这将阻止浏览器将其验证为URL

url = forms.URLField(max_length=200, widget=forms.TextInput, help_text="Please enter the url of the page")
另一个选项是向表单标记添加
novalidate
,但这将关闭整个表单的浏览器验证

<form method="post" novalidate>
  {{ form }}
</form>

{{form}}

您的输入是什么?你得到了/期望得到什么?“super().clean()”是什么意思?@Heri假设我想进入www.google.com,如果那样输入url,我会得到一个http://缺失的错误。因此,我正在寻找一个函数来自动预加'http://',如果您输入它,则不会引发验证错误?@lmr2391我不希望它引发验证错误如果表单的验证函数引发验证错误,或者此异常在调用桩的某个位置被捕获,消息保存到form.errors。所以你没有收到500服务器错误文本输入工作得很好,谢谢。我只剩下文档:()HTML5输入类型和浏览器验证。在我的例子中,因为我只需要小部件,所以我以如下形式添加了它:
widgets={'url':TextInput()}
。TextInput从django.forms导入。