Fixed #13613 -- Ensure that forms.URLField and forms.EmailField are used on a modelform. This ensures that fields are URL and Email fields are cleaned consistently when included on model forms. Thanks to amadison for the report.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@13475 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Russell Keith-Magee 2010-08-05 03:59:20 +00:00
parent fc374976e5
commit aa93f8c2f0
3 changed files with 55 additions and 2 deletions

View File

@ -795,6 +795,14 @@ class EmailField(CharField):
kwargs['max_length'] = kwargs.get('max_length', 75)
CharField.__init__(self, *args, **kwargs)
def formfield(self, **kwargs):
# As with CharField, this will cause email validation to be performed twice
defaults = {
'form_class': forms.EmailField,
}
defaults.update(kwargs)
return super(EmailField, self).formfield(**defaults)
class FilePathField(Field):
description = _("File path")
@ -1105,6 +1113,14 @@ class URLField(CharField):
CharField.__init__(self, verbose_name, name, **kwargs)
self.validators.append(validators.URLValidator(verify_exists=verify_exists))
def formfield(self, **kwargs):
# As with CharField, this will cause URL validation to be performed twice
defaults = {
'form_class': forms.URLField,
}
defaults.update(kwargs)
return super(URLField, self).formfield(**defaults)
class XMLField(TextField):
description = _("XML text")

View File

@ -54,3 +54,6 @@ class Author(models.Model):
class Author1(models.Model):
publication = models.OneToOneField(Publication, null=False)
full_name = models.CharField(max_length=255)
class Homepage(models.Model):
url = models.URLField(verify_exists=False)

View File

@ -6,7 +6,8 @@ from django.forms.models import modelform_factory, ModelChoiceField
from django.conf import settings
from django.test import TestCase
from models import Person, RealPerson, Triple, FilePathModel, Article, Publication, CustomFF, Author, Author1
from models import Person, RealPerson, Triple, FilePathModel, Article, \
Publication, CustomFF, Author, Author1, Homepage
class ModelMultipleChoiceFieldTests(TestCase):
@ -212,7 +213,40 @@ class TestTicket11183(TestCase):
def test_11183(self):
form1 = ModelChoiceForm()
field1 = form1.fields['person']
# To allow the widget to change the queryset of field1.widget.choices correctly,
# To allow the widget to change the queryset of field1.widget.choices correctly,
# without affecting other forms, the following must hold:
self.assert_(field1 is not ModelChoiceForm.base_fields['person'])
self.assert_(field1.widget.choices.field is field1)
class HomepageForm(forms.ModelForm):
class Meta:
model = Homepage
class URLFieldTests(TestCase):
def test_url_on_modelform(self):
"Check basic URL field validation on model forms"
self.assertFalse(HomepageForm({'url': 'foo'}).is_valid())
self.assertFalse(HomepageForm({'url': 'http://'}).is_valid())
self.assertFalse(HomepageForm({'url': 'http://example'}).is_valid())
self.assertFalse(HomepageForm({'url': 'http://example.'}).is_valid())
self.assertFalse(HomepageForm({'url': 'http://com.'}).is_valid())
self.assertTrue(HomepageForm({'url': 'http://localhost'}).is_valid())
self.assertTrue(HomepageForm({'url': 'http://example.com'}).is_valid())
self.assertTrue(HomepageForm({'url': 'http://www.example.com'}).is_valid())
self.assertTrue(HomepageForm({'url': 'http://www.example.com:8000'}).is_valid())
self.assertTrue(HomepageForm({'url': 'http://www.example.com/test'}).is_valid())
self.assertTrue(HomepageForm({'url': 'http://www.example.com:8000/test'}).is_valid())
self.assertTrue(HomepageForm({'url': 'http://example.com/foo/bar'}).is_valid())
def test_http_prefixing(self):
"If the http:// prefix is omitted on form input, the field adds it again. (Refs #13613)"
form = HomepageForm({'url': 'example.com'})
form.is_valid()
# self.assertTrue(form.is_valid())
# self.assertEquals(form.cleaned_data['url'], 'http://example.com/')
form = HomepageForm({'url': 'example.com/test'})
form.is_valid()
# self.assertTrue(form.is_valid())
# self.assertEquals(form.cleaned_data['url'], 'http://example.com/test')