Fixed #24428 -- Fixed has_changed for fields with coercion
Thanks Carsten Fuchs for the report.
This commit is contained in:
parent
767c33d1fa
commit
8714403614
|
@ -195,6 +195,7 @@ class Field(six.with_metaclass(RenameFieldMethods, object)):
|
||||||
data = self.to_python(data)
|
data = self.to_python(data)
|
||||||
if hasattr(self, '_coerce'):
|
if hasattr(self, '_coerce'):
|
||||||
data = self._coerce(data)
|
data = self._coerce(data)
|
||||||
|
initial_value = self._coerce(initial_value)
|
||||||
except ValidationError:
|
except ValidationError:
|
||||||
return True
|
return True
|
||||||
data_value = data if data is not None else ''
|
data_value = data if data is not None else ''
|
||||||
|
|
|
@ -1082,6 +1082,7 @@ class FieldsTests(SimpleTestCase):
|
||||||
f = TypedChoiceField(choices=[(1, "+1"), (-1, "-1")], coerce=int, required=True)
|
f = TypedChoiceField(choices=[(1, "+1"), (-1, "-1")], coerce=int, required=True)
|
||||||
self.assertFalse(f.has_changed(None, ''))
|
self.assertFalse(f.has_changed(None, ''))
|
||||||
self.assertFalse(f.has_changed(1, '1'))
|
self.assertFalse(f.has_changed(1, '1'))
|
||||||
|
self.assertFalse(f.has_changed('1', '1'))
|
||||||
|
|
||||||
def test_typedchoicefield_special_coerce(self):
|
def test_typedchoicefield_special_coerce(self):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -106,6 +106,23 @@ class Publication(models.Model):
|
||||||
return self.title
|
return self.title
|
||||||
|
|
||||||
|
|
||||||
|
def default_mode():
|
||||||
|
return 'di'
|
||||||
|
|
||||||
|
|
||||||
|
def default_category():
|
||||||
|
return 3
|
||||||
|
|
||||||
|
|
||||||
|
class PublicationDefaults(models.Model):
|
||||||
|
MODE_CHOICES = (('di', 'direct'), ('de', 'delayed'))
|
||||||
|
CATEGORY_CHOICES = ((1, 'Games'), (2, 'Comics'), (3, 'Novel'))
|
||||||
|
title = models.CharField(max_length=30)
|
||||||
|
date_published = models.DateField(default=datetime.date.today)
|
||||||
|
mode = models.CharField(max_length=2, choices=MODE_CHOICES, default=default_mode)
|
||||||
|
category = models.IntegerField(choices=CATEGORY_CHOICES, default=default_category)
|
||||||
|
|
||||||
|
|
||||||
class Author(models.Model):
|
class Author(models.Model):
|
||||||
publication = models.OneToOneField(Publication, null=True, blank=True)
|
publication = models.OneToOneField(Publication, null=True, blank=True)
|
||||||
full_name = models.CharField(max_length=255)
|
full_name = models.CharField(max_length=255)
|
||||||
|
|
|
@ -28,8 +28,9 @@ from .models import (
|
||||||
CustomErrorMessage, CustomFF, CustomFieldForExclusionModel, DateTimePost,
|
CustomErrorMessage, CustomFF, CustomFieldForExclusionModel, DateTimePost,
|
||||||
DerivedBook, DerivedPost, Document, ExplicitPK, FilePathModel,
|
DerivedBook, DerivedPost, Document, ExplicitPK, FilePathModel,
|
||||||
FlexibleDatePost, Homepage, ImprovedArticle, ImprovedArticleWithParentLink,
|
FlexibleDatePost, Homepage, ImprovedArticle, ImprovedArticleWithParentLink,
|
||||||
Inventory, Person, Photo, Post, Price, Product, Publication, Student,
|
Inventory, Person, Photo, Post, Price, Product, Publication,
|
||||||
StumpJoke, TextFile, Triple, Writer, WriterProfile, test_images,
|
PublicationDefaults, Student, StumpJoke, TextFile, Triple, Writer,
|
||||||
|
WriterProfile, test_images,
|
||||||
)
|
)
|
||||||
|
|
||||||
if test_images:
|
if test_images:
|
||||||
|
@ -2282,6 +2283,41 @@ class OtherModelFormTests(TestCase):
|
||||||
</select></p>"""
|
</select></p>"""
|
||||||
% {'blue_pk': colour.pk})
|
% {'blue_pk': colour.pk})
|
||||||
|
|
||||||
|
def test_callable_field_default(self):
|
||||||
|
class PublicationDefaultsForm(forms.ModelForm):
|
||||||
|
class Meta:
|
||||||
|
model = PublicationDefaults
|
||||||
|
fields = '__all__'
|
||||||
|
|
||||||
|
form = PublicationDefaultsForm()
|
||||||
|
self.assertHTMLEqual(
|
||||||
|
form.as_p(),
|
||||||
|
"""<p><label for="id_title">Title:</label> <input id="id_title" maxlength="30" name="title" type="text" /></p>
|
||||||
|
<p><label for="id_date_published">Date published:</label>
|
||||||
|
<input id="id_date_published" name="date_published" type="text" value="2015-03-04" />
|
||||||
|
<input id="initial-id_date_published" name="initial-date_published" type="hidden" value="2015-03-04" /></p>
|
||||||
|
<p><label for="id_mode">Mode:</label> <select id="id_mode" name="mode">
|
||||||
|
<option value="di" selected="selected">direct</option>
|
||||||
|
<option value="de">delayed</option></select>
|
||||||
|
<input id="initial-id_mode" name="initial-mode" type="hidden" value="di" /></p>
|
||||||
|
<p><label for="id_category">Category:</label> <select id="id_category" name="category">
|
||||||
|
<option value="1">Games</option>
|
||||||
|
<option value="2">Comics</option>
|
||||||
|
<option value="3" selected="selected">Novel</option></select>
|
||||||
|
<input id="initial-id_category" name="initial-category" type="hidden" value="3" />"""
|
||||||
|
)
|
||||||
|
empty_data = {
|
||||||
|
'title': '',
|
||||||
|
'date_published': '2015-03-04',
|
||||||
|
'initial-date_published': '2015-03-04',
|
||||||
|
'mode': 'di',
|
||||||
|
'initial-mode': 'di',
|
||||||
|
'category': '3',
|
||||||
|
'initial-category': '3',
|
||||||
|
}
|
||||||
|
bound_form = PublicationDefaultsForm(empty_data)
|
||||||
|
self.assertFalse(bound_form.has_changed())
|
||||||
|
|
||||||
|
|
||||||
class ModelFormCustomErrorTests(TestCase):
|
class ModelFormCustomErrorTests(TestCase):
|
||||||
def test_custom_error_messages(self):
|
def test_custom_error_messages(self):
|
||||||
|
|
Loading…
Reference in New Issue