Loading AUTHORS +1 −0 Original line number Diff line number Diff line Loading @@ -646,6 +646,7 @@ answer newbie questions, and generally made Django that much better: Rick Wagner <rwagner@physics.ucsd.edu> Gavin Wahl <gavinwahl@gmail.com> wam-djangobug@wamber.net Albert Wang <aywang31@gmail.com> Wang Chun <wangchun@exoweb.net> Filip Wasilewski <filip.wasilewski@gmail.com> Dan Watson <http://danwatson.net/> Loading django/db/models/fields/related.py +4 −3 Original line number Diff line number Diff line Loading @@ -1692,11 +1692,12 @@ class ForeignKey(ForeignObject): return field_default def get_db_prep_save(self, value, connection): if value == '' or value is None: if value is None or (value == '' and (not self.related_field.empty_strings_allowed or connection.features.interprets_empty_strings_as_nulls)): return None else: return self.related_field.get_db_prep_save(value, connection=connection) return self.related_field.get_db_prep_save(value, connection=connection) def value_to_string(self, obj): if not obj: Loading django/db/models/query.py +5 −2 Original line number Diff line number Diff line Loading @@ -1416,9 +1416,12 @@ def get_cached_row(row, index_start, using, klass_info, offset=0, klass, field_names, field_count, related_fields, reverse_related_fields, pk_idx = klass_info fields = row[index_start:index_start + field_count] # If the pk column is None (or the Oracle equivalent ''), then the related # If the pk column is None (or the equivalent '' in the case the # connection interprets empty strings as nulls), then the related # object must be non-existent - set the relation to None. if fields[pk_idx] is None or fields[pk_idx] == '': if (fields[pk_idx] is None or (connections[using].features.interprets_empty_strings_as_nulls and fields[pk_idx] == '')): obj = None elif field_names: fields = list(fields) Loading tests/model_fields/models.py +9 −0 Original line number Diff line number Diff line Loading @@ -72,12 +72,21 @@ class BooleanModel(models.Model): string = models.CharField(max_length=10, default='abc') class PrimaryKeyCharModel(models.Model): string = models.CharField(max_length=10, primary_key=True) class FksToBooleans(models.Model): """Model wih FKs to models with {Null,}BooleanField's, #15040""" bf = models.ForeignKey(BooleanModel) nbf = models.ForeignKey(NullBooleanModel) class FkToChar(models.Model): """Model with FK to a model with a CharField primary key, #19299""" out = models.ForeignKey(PrimaryKeyCharModel) class RenamedField(models.Model): modelname = models.IntegerField(name="fieldname", choices=((1, 'One'),)) Loading tests/model_fields/tests.py +13 −2 Original line number Diff line number Diff line Loading @@ -22,8 +22,8 @@ from django.utils.functional import lazy from .models import ( Foo, Bar, Whiz, BigD, BigS, BigInt, Post, NullBooleanModel, BooleanModel, DataModel, Document, RenamedField, VerboseNameField, FksToBooleans) BooleanModel, PrimaryKeyCharModel, DataModel, Document, RenamedField, VerboseNameField, FksToBooleans, FkToChar) class BasicFieldTests(test.TestCase): Loading Loading @@ -146,6 +146,17 @@ class ForeignKeyTests(test.TestCase): b = Bar.objects.create(b="bcd") self.assertEqual(b.a, a) @test.skipIfDBFeature('interprets_empty_strings_as_nulls') def test_empty_string_fk(self): """ Test that foreign key values to empty strings don't get converted to None (#19299) """ char_model_empty = PrimaryKeyCharModel.objects.create(string='') fk_model_empty = FkToChar.objects.create(out=char_model_empty) fk_model_empty = FkToChar.objects.select_related('out').get(id=fk_model_empty.pk) self.assertEqual(fk_model_empty.out, char_model_empty) class DateTimeFieldTests(unittest.TestCase): def test_datetimefield_to_python_usecs(self): Loading Loading
AUTHORS +1 −0 Original line number Diff line number Diff line Loading @@ -646,6 +646,7 @@ answer newbie questions, and generally made Django that much better: Rick Wagner <rwagner@physics.ucsd.edu> Gavin Wahl <gavinwahl@gmail.com> wam-djangobug@wamber.net Albert Wang <aywang31@gmail.com> Wang Chun <wangchun@exoweb.net> Filip Wasilewski <filip.wasilewski@gmail.com> Dan Watson <http://danwatson.net/> Loading
django/db/models/fields/related.py +4 −3 Original line number Diff line number Diff line Loading @@ -1692,11 +1692,12 @@ class ForeignKey(ForeignObject): return field_default def get_db_prep_save(self, value, connection): if value == '' or value is None: if value is None or (value == '' and (not self.related_field.empty_strings_allowed or connection.features.interprets_empty_strings_as_nulls)): return None else: return self.related_field.get_db_prep_save(value, connection=connection) return self.related_field.get_db_prep_save(value, connection=connection) def value_to_string(self, obj): if not obj: Loading
django/db/models/query.py +5 −2 Original line number Diff line number Diff line Loading @@ -1416,9 +1416,12 @@ def get_cached_row(row, index_start, using, klass_info, offset=0, klass, field_names, field_count, related_fields, reverse_related_fields, pk_idx = klass_info fields = row[index_start:index_start + field_count] # If the pk column is None (or the Oracle equivalent ''), then the related # If the pk column is None (or the equivalent '' in the case the # connection interprets empty strings as nulls), then the related # object must be non-existent - set the relation to None. if fields[pk_idx] is None or fields[pk_idx] == '': if (fields[pk_idx] is None or (connections[using].features.interprets_empty_strings_as_nulls and fields[pk_idx] == '')): obj = None elif field_names: fields = list(fields) Loading
tests/model_fields/models.py +9 −0 Original line number Diff line number Diff line Loading @@ -72,12 +72,21 @@ class BooleanModel(models.Model): string = models.CharField(max_length=10, default='abc') class PrimaryKeyCharModel(models.Model): string = models.CharField(max_length=10, primary_key=True) class FksToBooleans(models.Model): """Model wih FKs to models with {Null,}BooleanField's, #15040""" bf = models.ForeignKey(BooleanModel) nbf = models.ForeignKey(NullBooleanModel) class FkToChar(models.Model): """Model with FK to a model with a CharField primary key, #19299""" out = models.ForeignKey(PrimaryKeyCharModel) class RenamedField(models.Model): modelname = models.IntegerField(name="fieldname", choices=((1, 'One'),)) Loading
tests/model_fields/tests.py +13 −2 Original line number Diff line number Diff line Loading @@ -22,8 +22,8 @@ from django.utils.functional import lazy from .models import ( Foo, Bar, Whiz, BigD, BigS, BigInt, Post, NullBooleanModel, BooleanModel, DataModel, Document, RenamedField, VerboseNameField, FksToBooleans) BooleanModel, PrimaryKeyCharModel, DataModel, Document, RenamedField, VerboseNameField, FksToBooleans, FkToChar) class BasicFieldTests(test.TestCase): Loading Loading @@ -146,6 +146,17 @@ class ForeignKeyTests(test.TestCase): b = Bar.objects.create(b="bcd") self.assertEqual(b.a, a) @test.skipIfDBFeature('interprets_empty_strings_as_nulls') def test_empty_string_fk(self): """ Test that foreign key values to empty strings don't get converted to None (#19299) """ char_model_empty = PrimaryKeyCharModel.objects.create(string='') fk_model_empty = FkToChar.objects.create(out=char_model_empty) fk_model_empty = FkToChar.objects.select_related('out').get(id=fk_model_empty.pk) self.assertEqual(fk_model_empty.out, char_model_empty) class DateTimeFieldTests(unittest.TestCase): def test_datetimefield_to_python_usecs(self): Loading