summaryrefslogtreecommitdiff
path: root/django/db/models/options.py
diff options
context:
space:
mode:
authorTom Forbes <tom@tomforb.es>2020-07-12 13:59:57 +0100
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2020-12-15 11:25:46 +0100
commitb5e12d490af3debca8c55ab3c1698189fdedbbdb (patch)
tree5fe3005ac567f3addf78b81ae033191e2fa642f4 /django/db/models/options.py
parentb960e4ed722a04a9db0d35293f76e253eedf9126 (diff)
downloaddjango-b5e12d490af3debca8c55ab3c1698189fdedbbdb.tar.gz
Fixed #31007 -- Allowed specifying type of auto-created primary keys.
This also changes the default type of auto-created primary keys for new apps and projects to BigAutoField.
Diffstat (limited to 'django/db/models/options.py')
-rw-r--r--django/db/models/options.py37
1 files changed, 35 insertions, 2 deletions
diff --git a/django/db/models/options.py b/django/db/models/options.py
index 0e28b6812a..4028e05b99 100644
--- a/django/db/models/options.py
+++ b/django/db/models/options.py
@@ -5,12 +5,13 @@ from collections import defaultdict
from django.apps import apps
from django.conf import settings
-from django.core.exceptions import FieldDoesNotExist
+from django.core.exceptions import FieldDoesNotExist, ImproperlyConfigured
from django.db import connections
from django.db.models import AutoField, Manager, OrderWrt, UniqueConstraint
from django.db.models.query_utils import PathInfo
from django.utils.datastructures import ImmutableList, OrderedSet
from django.utils.functional import cached_property
+from django.utils.module_loading import import_string
from django.utils.text import camel_case_to_spaces, format_lazy
from django.utils.translation import override
@@ -217,6 +218,37 @@ class Options:
new_objs.append(obj)
return new_objs
+ def _get_default_pk_class(self):
+ pk_class_path = getattr(
+ self.app_config,
+ 'default_auto_field',
+ settings.DEFAULT_AUTO_FIELD,
+ )
+ if self.app_config and self.app_config._is_default_auto_field_overridden:
+ app_config_class = type(self.app_config)
+ source = (
+ f'{app_config_class.__module__}.'
+ f'{app_config_class.__qualname__}.default_auto_field'
+ )
+ else:
+ source = 'DEFAULT_AUTO_FIELD'
+ if not pk_class_path:
+ raise ImproperlyConfigured(f'{source} must not be empty.')
+ try:
+ pk_class = import_string(pk_class_path)
+ except ImportError as e:
+ msg = (
+ f"{source} refers to the module '{pk_class_path}' that could "
+ f"not be imported."
+ )
+ raise ImproperlyConfigured(msg) from e
+ if not issubclass(pk_class, AutoField):
+ raise ValueError(
+ f"Primary key '{pk_class_path}' referred by {source} must "
+ f"subclass AutoField."
+ )
+ return pk_class
+
def _prepare(self, model):
if self.order_with_respect_to:
# The app registry will not be ready at this point, so we cannot
@@ -250,7 +282,8 @@ class Options:
field.primary_key = True
self.setup_pk(field)
else:
- auto = AutoField(verbose_name='ID', primary_key=True, auto_created=True)
+ pk_class = self._get_default_pk_class()
+ auto = pk_class(verbose_name='ID', primary_key=True, auto_created=True)
model.add_to_class('id', auto)
def add_manager(self, manager):