Fixed #8316 -- Put tighter restrictions on the type of Foreign Key fields

created for MySQL (because MySQL + InnoDB has those restrictions).
Patch from julianb.


git-svn-id: http://code.djangoproject.com/svn/django/trunk@8782 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Malcolm Tredinnick 2008-09-01 00:49:03 +00:00
parent 032d654967
commit 4480645ac3
4 changed files with 34 additions and 2 deletions

View File

@ -71,6 +71,9 @@ class BaseDatabaseFeatures(object):
interprets_empty_strings_as_nulls = False
can_use_chunked_reads = True
uses_savepoints = False
# If True, don't use integer foreign keys referring to, e.g., positive
# integer primary keys.
related_fields_match_type = False
class BaseDatabaseOperations(object):
"""

View File

@ -110,6 +110,7 @@ class CursorWrapper(object):
class DatabaseFeatures(BaseDatabaseFeatures):
empty_fetchmany_value = ()
update_can_self_select = False
related_fields_match_type = True
class DatabaseOperations(BaseDatabaseOperations):
def date_extract_sql(self, lookup_type, field_name):

View File

@ -695,8 +695,13 @@ class ForeignKey(RelatedField, Field):
# of the field to which it points. An exception is if the ForeignKey
# points to an AutoField/PositiveIntegerField/PositiveSmallIntegerField,
# in which case the column type is simply that of an IntegerField.
# If the database needs similar types for key fields however, the only
# thing we can do is making AutoField an IntegerField.
rel_field = self.rel.get_related_field()
if isinstance(rel_field, (AutoField, PositiveIntegerField, PositiveSmallIntegerField)):
if (isinstance(rel_field, AutoField) or
(not connection.features.related_fields_match_type and
isinstance(rel_field, (PositiveIntegerField,
PositiveSmallIntegerField)))):
return IntegerField().db_type()
return rel_field.db_type()

View File

@ -32,6 +32,20 @@ class Party(models.Model):
class Event(models.Model):
when = models.DateTimeField()
class Department(models.Model):
id = models.PositiveIntegerField(primary_key=True)
name = models.CharField(max_length=200)
def __unicode__(self):
return self.name
class Worker(models.Model):
department = models.ForeignKey(Department)
name = models.CharField(max_length=200)
def __unicode__(self):
return self.name
__test__ = {'API_TESTS': """
(NOTE: Part of the regression test here is merely parsing the model
declaration. The verbose_name, in particular, did not always work.)
@ -95,5 +109,14 @@ u''
datetime.datetime(2000, 1, 1, 13, 1, 1)
>>> e.get_previous_by_when().when
datetime.datetime(2000, 1, 1, 6, 1, 1)
# Check Department and Worker
>>> d = Department(id=10, name='IT')
>>> d.save()
>>> w = Worker(department=d, name='Full-time')
>>> w.save()
>>> w
<Worker: Full-time>
"""
}