clean方法不适用于URLField

时间:2018-01-12 19:35:36

标签: django

我正在处理我要求用户输入网址的内容。然后我意识到大多数用户都没有提前支持' http://'在写一个URL然后我决定使用一个干净的方法。在检查了很多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',)

不幸的是,由于我仍然收到无效的网址错误,因此无法正常工作。有什么我想念的吗?如果是的话,是什么?

2 个答案:

答案 0 :(得分:1)

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

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

一种选择是将输入更改为TextInput,这会阻止您的浏览器将其验证为网址。

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>

答案 1 :(得分:0)

由于您只验证了一个字段,因此您不应该在表单清除方法中执行此操作,而应使用clean_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