diff options
Diffstat (limited to 'django/db')
| -rw-r--r-- | django/db/backends/ado_mssql/creation.py | 1 | ||||
| -rw-r--r-- | django/db/backends/mysql/creation.py | 1 | ||||
| -rw-r--r-- | django/db/backends/mysql_old/creation.py | 1 | ||||
| -rw-r--r-- | django/db/backends/oracle/creation.py | 1 | ||||
| -rw-r--r-- | django/db/backends/postgresql/creation.py | 1 | ||||
| -rw-r--r-- | django/db/backends/sqlite3/creation.py | 1 | ||||
| -rw-r--r-- | django/db/models/fields/__init__.py | 25 | ||||
| -rw-r--r-- | django/db/models/fields/related.py | 27 |
8 files changed, 51 insertions, 7 deletions
diff --git a/django/db/backends/ado_mssql/creation.py b/django/db/backends/ado_mssql/creation.py index a1098ea43e..e7d612817c 100644 --- a/django/db/backends/ado_mssql/creation.py +++ b/django/db/backends/ado_mssql/creation.py @@ -12,7 +12,6 @@ DATA_TYPES = { 'ImageField': 'varchar(100)', 'IntegerField': 'int', 'IPAddressField': 'char(15)', - 'ManyToManyField': None, 'NullBooleanField': 'bit', 'OneToOneField': 'int', 'PhoneNumberField': 'varchar(20)', diff --git a/django/db/backends/mysql/creation.py b/django/db/backends/mysql/creation.py index 1b23fbff6e..e4b5eaf2c8 100644 --- a/django/db/backends/mysql/creation.py +++ b/django/db/backends/mysql/creation.py @@ -16,7 +16,6 @@ DATA_TYPES = { 'ImageField': 'varchar(100)', 'IntegerField': 'integer', 'IPAddressField': 'char(15)', - 'ManyToManyField': None, 'NullBooleanField': 'bool', 'OneToOneField': 'integer', 'PhoneNumberField': 'varchar(20)', diff --git a/django/db/backends/mysql_old/creation.py b/django/db/backends/mysql_old/creation.py index 1b23fbff6e..e4b5eaf2c8 100644 --- a/django/db/backends/mysql_old/creation.py +++ b/django/db/backends/mysql_old/creation.py @@ -16,7 +16,6 @@ DATA_TYPES = { 'ImageField': 'varchar(100)', 'IntegerField': 'integer', 'IPAddressField': 'char(15)', - 'ManyToManyField': None, 'NullBooleanField': 'bool', 'OneToOneField': 'integer', 'PhoneNumberField': 'varchar(20)', diff --git a/django/db/backends/oracle/creation.py b/django/db/backends/oracle/creation.py index f7903bce4f..420b98bd9e 100644 --- a/django/db/backends/oracle/creation.py +++ b/django/db/backends/oracle/creation.py @@ -19,7 +19,6 @@ DATA_TYPES = { 'ImageField': 'NVARCHAR2(100)', 'IntegerField': 'NUMBER(11)', 'IPAddressField': 'VARCHAR2(15)', - 'ManyToManyField': None, 'NullBooleanField': 'NUMBER(1) CHECK ((%(column)s IN (0,1)) OR (%(column)s IS NULL))', 'OneToOneField': 'NUMBER(11)', 'PhoneNumberField': 'VARCHAR2(20)', diff --git a/django/db/backends/postgresql/creation.py b/django/db/backends/postgresql/creation.py index 4646b68ab8..fde094de7f 100644 --- a/django/db/backends/postgresql/creation.py +++ b/django/db/backends/postgresql/creation.py @@ -16,7 +16,6 @@ DATA_TYPES = { 'ImageField': 'varchar(100)', 'IntegerField': 'integer', 'IPAddressField': 'inet', - 'ManyToManyField': None, 'NullBooleanField': 'boolean', 'OneToOneField': 'integer', 'PhoneNumberField': 'varchar(20)', diff --git a/django/db/backends/sqlite3/creation.py b/django/db/backends/sqlite3/creation.py index e63046ab7d..ab7442252e 100644 --- a/django/db/backends/sqlite3/creation.py +++ b/django/db/backends/sqlite3/creation.py @@ -15,7 +15,6 @@ DATA_TYPES = { 'ImageField': 'varchar(100)', 'IntegerField': 'integer', 'IPAddressField': 'char(15)', - 'ManyToManyField': None, 'NullBooleanField': 'bool', 'OneToOneField': 'integer', 'PhoneNumberField': 'varchar(20)', diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py index bc6d551a4c..5e3509857b 100644 --- a/django/db/models/fields/__init__.py +++ b/django/db/models/fields/__init__.py @@ -1,3 +1,4 @@ +from django.db import get_creation_module from django.db.models import signals from django.dispatch import dispatcher from django.conf import settings @@ -117,6 +118,30 @@ class Field(object): """ return value + def db_type(self): + """ + Returns the database column data type for this field, taking into + account the DATABASE_ENGINE setting. + """ + # The default implementation of this method looks at the + # backend-specific DATA_TYPES dictionary, looking up the field by its + # "internal type". + # + # A Field class can implement the get_internal_type() method to specify + # which *preexisting* Django Field class it's most similar to -- i.e., + # an XMLField is represented by a TEXT column type, which is the same + # as the TextField Django field type, which means XMLField's + # get_internal_type() returns 'TextField'. + # + # But the limitation of the get_internal_type() / DATA_TYPES approach + # is that it cannot handle database column types that aren't already + # mapped to one of the built-in Django field types. In this case, you + # can implement db_type() instead of get_internal_type() to specify + # exactly which wacky database column type you want to use. + data_types = get_creation_module().DATA_TYPES + internal_type = self.get_internal_type() + return data_types[internal_type] % self.__dict__ + def validate_full(self, field_data, all_data): """ Returns a list of errors for this field. This is the main interface, diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py index 152af10545..c4284f04b1 100644 --- a/django/db/models/fields/related.py +++ b/django/db/models/fields/related.py @@ -1,6 +1,6 @@ from django.db import backend, transaction from django.db.models import signals, get_model -from django.db.models.fields import AutoField, Field, IntegerField, get_ul_class +from django.db.models.fields import AutoField, Field, IntegerField, PositiveIntegerField, PositiveSmallIntegerField, get_ul_class from django.db.models.related import RelatedObject from django.utils.text import capfirst from django.utils.translation import ugettext_lazy, string_concat, ungettext, ugettext as _ @@ -556,6 +556,16 @@ class ForeignKey(RelatedField, Field): defaults.update(kwargs) return super(ForeignKey, self).formfield(**defaults) + def db_type(self): + # The database column type of a ForeignKey is the column type + # 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. + rel_field = self.rel.get_related_field() + if isinstance(rel_field, (AutoField, PositiveIntegerField, PositiveSmallIntegerField)): + return IntegerField().db_type() + return rel_field.db_type() + class OneToOneField(RelatedField, IntegerField): def __init__(self, to, to_field=None, **kwargs): try: @@ -622,6 +632,16 @@ class OneToOneField(RelatedField, IntegerField): defaults.update(kwargs) return super(OneToOneField, self).formfield(**defaults) + def db_type(self): + # The database column type of a OneToOneField is the column type + # of the field to which it points. An exception is if the OneToOneField + # points to an AutoField/PositiveIntegerField/PositiveSmallIntegerField, + # in which case the column type is simply that of an IntegerField. + rel_field = self.rel.get_related_field() + if isinstance(rel_field, (AutoField, PositiveIntegerField, PositiveSmallIntegerField)): + return IntegerField().db_type() + return rel_field.db_type() + class ManyToManyField(RelatedField, Field): def __init__(self, to, **kwargs): kwargs['verbose_name'] = kwargs.get('verbose_name', None) @@ -745,6 +765,11 @@ class ManyToManyField(RelatedField, Field): defaults['initial'] = [i._get_pk_val() for i in defaults['initial']] return super(ManyToManyField, self).formfield(**defaults) + def db_type(self): + # A ManyToManyField is not represented by a single column, + # so return None. + return None + class ManyToOneRel(object): def __init__(self, to, field_name, num_in_admin=3, min_num_in_admin=None, max_num_in_admin=None, num_extra_on_change=1, edit_inline=False, |
