ModelForm clean_xxxx()适用于CharField,而不适用于URLField。Django 1.5
在验证URL字段之前,如何删除空白 使用“clean_u[fieldname]()”似乎是从中记录的方式,但它不适用于URLField。我将其简化为一个基本测试用例,可以在django shell中运行:ModelForm clean_xxxx()适用于CharField,而不适用于URLField。Django 1.5,django,django-models,django-forms,Django,Django Models,Django Forms,在验证URL字段之前,如何删除空白 使用“clean_u[fieldname]()”似乎是从中记录的方式,但它不适用于URLField。我将其简化为一个基本测试用例,可以在django shell中运行: class XXXTestModel(models.Model): url = models.URLField('URL',null=True,blank=True) name = models.CharField(max_length=200) class XXXTestF
class XXXTestModel(models.Model):
url = models.URLField('URL',null=True,blank=True)
name = models.CharField(max_length=200)
class XXXTestForm(ModelForm):
def clean_url(self):
return self.cleaned_data['url'].strip()
def clean_name(self):
return self.cleaned_data['name'].strip()
class Meta:
model = XXXTestModel
fields = (
'url',
)
使用Django shell进行测试,包括:
>>> django.VERSION
(1, 5, 1, 'final', 0)
>>> from xxx import XXXTestForm,XXXTestModel
>>> data = dict(url=' http://www.example.com/ ',name=' example ')
>>> f=XXXTestForm(data)
>>> f.is_valid();f.errors
False
{'url': [u'Enter a valid URL.']}
>>> f.cleaned_data
{'name': example'}
关于堆栈溢出,这个问题有很多重复,但没有一个答案可以指导解决方案。这里的问题是django.forms.URLField如何工作
django.forms.Field.clean
定义为:
def clean(self, value):
"""
Validates the given value and returns its "cleaned" value as an
appropriate Python object.
Raises ValidationError for any errors.
"""
value = self.to_python(value)
self.validate(value)
self.run_validators(value)
return value
请注意,在任何验证之前都会执行to_python
。这就是这里的问题-django.forms.URLField
无法理解您给它的值,因此它生成的值无法通过已定义为django.forms.URLField
一部分的验证器集(即,django.core.validators.urlvidator
)
它失败的原因是django试图“规范化”URL。这包括在需要的地方添加“http://”
。当给出示例url时,“http://www.example.com “
,django使用urlparse.urlspit
获取url的“部分”。但是,前导空格将其弄乱,整个值将成为路径的一部分。因此,django找不到任何方案
,并将URL重新配置为“http:/http://www.example.com “
。然后将其提交给django.core.validators.urlvidator
,这显然是失败的
为了避免这种情况,我们需要为表单定义自己的URLField
from django import forms
class StrippedURLField(forms.URLField):
def to_python(self, value):
return super(StrippedURLField, self).to_python(value and value.strip())
使用此方法可以确保整个过程按预期进行,并且我们不需要使用clean\uURL
方法。(注意:在可能的情况下,您应该使用clean.*
,但在这里不是)
如果在def clean\u url
中打印自清理的数据['url']
,您会得到什么?什么都没有。它似乎永远不会被调用。(以上是一个可以粘贴到django shell中的独立示例)。感谢您的出色回答,这非常值得50分。
class XXXTestForm(forms.ModelForm):
url = StrippedURLField(blank=True, null=True)