Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Fixed #19299 -- Fixed Nullification of Foreign Keys To CharFields

Thanks tunixman for the report and Baptiste Mispelon and
Shai Berger for reviews.
  • Loading branch information...
commit 8bbdcc76e4a84cde92b8dbfd01581d098bd2187d 1 parent 4d4e0ea
@albertyw albertyw authored timgraham committed
View
1  AUTHORS
@@ -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/>
View
7 django/db/models/fields/related.py
@@ -1692,11 +1692,12 @@ def get_default(self):
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:
View
7 django/db/models/query.py
@@ -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)
View
9 tests/model_fields/models.py
@@ -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'),))
View
15 tests/model_fields/tests.py
@@ -22,8 +22,8 @@
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):
@@ -146,6 +146,17 @@ def test_callable_default(self):
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):
Please sign in to comment.
Something went wrong with that request. Please try again.