summaryrefslogtreecommitdiff
path: root/django/db
diff options
context:
space:
mode:
Diffstat (limited to 'django/db')
-rw-r--r--django/db/backends/ado_mssql/creation.py1
-rw-r--r--django/db/backends/mysql/creation.py1
-rw-r--r--django/db/backends/mysql_old/creation.py1
-rw-r--r--django/db/backends/oracle/creation.py1
-rw-r--r--django/db/backends/postgresql/creation.py1
-rw-r--r--django/db/backends/sqlite3/creation.py1
-rw-r--r--django/db/models/fields/__init__.py25
-rw-r--r--django/db/models/fields/related.py27
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,