Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

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

…elds

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
  • Loading branch information...
commit 4480645ac3b4d3b72ee2880c774f849965d555d4 1 parent 032d654
@malcolmt malcolmt authored
View
3  django/db/backends/__init__.py
@@ -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
1  django/db/backends/mysql/base.py
@@ -110,6 +110,7 @@ def __iter__(self):
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
9 django/db/models/fields/related.py
@@ -684,7 +684,7 @@ def contribute_to_class(self, cls, name):
def contribute_to_related_class(self, cls, related):
setattr(cls, related.get_accessor_name(), ForeignRelatedObjectsDescriptor(related))
-
+
def formfield(self, **kwargs):
defaults = {'form_class': forms.ModelChoiceField, 'queryset': self.rel.to._default_manager.complex_filter(self.rel.limit_choices_to)}
defaults.update(kwargs)
@@ -695,8 +695,13 @@ def db_type(self):
# 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
23 tests/regressiontests/model_regress/models.py
@@ -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 @@ class Event(models.Model):
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>
+
"""
}
Please sign in to comment.
Something went wrong with that request. Please try again.