diff --git a/django/db/backends/base/schema.py b/django/db/backends/base/schema.py index de4886837e..6303248127 100644 --- a/django/db/backends/base/schema.py +++ b/django/db/backends/base/schema.py @@ -13,7 +13,7 @@ from django.db.backends.ddl_references import ( Table, ) from django.db.backends.utils import names_digest, split_identifier, truncate_name -from django.db.models import NOT_PROVIDED, Deferrable, Index +from django.db.models import Deferrable, Index from django.db.models.fields.composite import CompositePrimaryKey from django.db.models.sql import Query from django.db.transaction import TransactionManagementError, atomic @@ -318,7 +318,7 @@ class BaseDatabaseSchemaEditor: # Work out nullability. null = field.null # Add database default. - if field.db_default is not NOT_PROVIDED: + if field.has_db_default(): default_sql, default_params = self.db_default_sql(field) yield f"DEFAULT {default_sql}" params.extend(default_params) @@ -775,7 +775,7 @@ class BaseDatabaseSchemaEditor: self.execute(sql, params or None) # Drop the default if we need to if ( - field.db_default is NOT_PROVIDED + not field.has_db_default() and not self.skip_default_on_alter(field) and self.effective_default(field) is not None ): @@ -1108,15 +1108,15 @@ class BaseDatabaseSchemaEditor: actions.append(fragment) post_actions.extend(other_actions) - if new_field.db_default is not NOT_PROVIDED: + if new_field.has_db_default(): if ( - old_field.db_default is NOT_PROVIDED + not old_field.has_db_default() or new_field.db_default != old_field.db_default ): actions.append( self._alter_column_database_default_sql(model, old_field, new_field) ) - elif old_field.db_default is not NOT_PROVIDED: + elif old_field.has_db_default(): actions.append( self._alter_column_database_default_sql( model, old_field, new_field, drop=True @@ -1130,11 +1130,7 @@ class BaseDatabaseSchemaEditor: # 4. Drop the default again. # Default change? needs_database_default = False - if ( - old_field.null - and not new_field.null - and new_field.db_default is NOT_PROVIDED - ): + if old_field.null and not new_field.null and not new_field.has_db_default(): old_default = self.effective_default(old_field) new_default = self.effective_default(new_field) if ( @@ -1153,7 +1149,7 @@ class BaseDatabaseSchemaEditor: null_actions.append(fragment) # Only if we have a default and there is a change from NULL to NOT NULL four_way_default_alteration = ( - new_field.has_default() or new_field.db_default is not NOT_PROVIDED + new_field.has_default() or new_field.has_db_default() ) and (old_field.null and not new_field.null) if actions or null_actions: if not four_way_default_alteration: @@ -1175,7 +1171,7 @@ class BaseDatabaseSchemaEditor: params, ) if four_way_default_alteration: - if new_field.db_default is NOT_PROVIDED: + if not new_field.has_db_default(): default_sql = "%s" params = [new_default] else: diff --git a/django/db/backends/mysql/schema.py b/django/db/backends/mysql/schema.py index 8651348ee2..b4192bb8cc 100644 --- a/django/db/backends/mysql/schema.py +++ b/django/db/backends/mysql/schema.py @@ -222,7 +222,7 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor): Keep the NULL and DEFAULT properties of the old field. If it has changed, it will be handled separately. """ - if field.db_default is not NOT_PROVIDED: + if field.has_db_default(): default_sql, params = self.db_default_sql(field) default_sql %= tuple(self.quote_value(p) for p in params) new_type += f" DEFAULT {default_sql}" @@ -266,7 +266,7 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor): return f" COMMENT {comment_sql}" def _alter_column_null_sql(self, model, old_field, new_field): - if new_field.db_default is NOT_PROVIDED: + if not new_field.has_db_default(): return super()._alter_column_null_sql(model, old_field, new_field) new_db_params = new_field.db_parameters(connection=self.connection) diff --git a/django/db/backends/sqlite3/schema.py b/django/db/backends/sqlite3/schema.py index 6da9852282..3617d17fac 100644 --- a/django/db/backends/sqlite3/schema.py +++ b/django/db/backends/sqlite3/schema.py @@ -6,7 +6,7 @@ from django.db import NotSupportedError from django.db.backends.base.schema import BaseDatabaseSchemaEditor from django.db.backends.ddl_references import Statement from django.db.backends.utils import strip_quotes -from django.db.models import NOT_PROVIDED, CompositePrimaryKey, UniqueConstraint +from django.db.models import CompositePrimaryKey, UniqueConstraint class DatabaseSchemaEditor(BaseDatabaseSchemaEditor): @@ -144,7 +144,7 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor): body[create_field.name] = create_field # Choose a default and insert it into the copy map if ( - create_field.db_default is NOT_PROVIDED + not create_field.has_db_default() and not (create_field.many_to_many or create_field.generated) and create_field.concrete ): @@ -161,7 +161,7 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor): if new_field.generated: continue if old_field.null and not new_field.null: - if new_field.db_default is NOT_PROVIDED: + if not new_field.has_db_default(): default = self.prepare_default(self.effective_default(new_field)) else: default, _ = self.db_default_sql(new_field) @@ -321,10 +321,7 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor): or self.effective_default(field) is not None # Fields with non-constant defaults cannot by handled by ALTER # TABLE ADD COLUMN statement. - or ( - field.db_default is not NOT_PROVIDED - and not isinstance(field.db_default, Value) - ) + or (field.has_db_default() and not isinstance(field.db_default, Value)) ): self._remake_table(model, create_field=field) else: diff --git a/django/db/migrations/autodetector.py b/django/db/migrations/autodetector.py index 1dc6377494..3475823003 100644 --- a/django/db/migrations/autodetector.py +++ b/django/db/migrations/autodetector.py @@ -1135,7 +1135,7 @@ class MigrationAutodetector: preserve_default = ( field.null or field.has_default() - or field.db_default is not models.NOT_PROVIDED + or field.has_db_default() or field.many_to_many or (field.blank and field.empty_strings_allowed) or (isinstance(field, time_fields) and field.auto_now) @@ -1150,11 +1150,7 @@ class MigrationAutodetector: field.default = self.questioner.ask_not_null_addition( field_name, model_name ) - if ( - field.unique - and field.default is not models.NOT_PROVIDED - and callable(field.default) - ): + if field.unique and field.has_default() and callable(field.default): self.questioner.ask_unique_callable_default_addition(field_name, model_name) self.add_operation( app_label, @@ -1296,7 +1292,7 @@ class MigrationAutodetector: old_field.null and not new_field.null and not new_field.has_default() - and new_field.db_default is models.NOT_PROVIDED + and not new_field.has_db_default() and not new_field.many_to_many ): field = new_field.clone() diff --git a/django/db/models/base.py b/django/db/models/base.py index 6d66080c20..180df0cff2 100644 --- a/django/db/models/base.py +++ b/django/db/models/base.py @@ -1118,10 +1118,7 @@ class Model(AltersData, metaclass=ModelBase): and not force_insert and not force_update and self._state.adding - and ( - (meta.pk.default and meta.pk.default is not NOT_PROVIDED) - or (meta.pk.db_default and meta.pk.db_default is not NOT_PROVIDED) - ) + and (meta.pk.has_default() or meta.pk.has_db_default()) ): force_insert = True # If possible, try an UPDATE. If that doesn't update anything, do an INSERT. diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py index c4a730f47b..ba8cf472c3 100644 --- a/django/db/models/fields/__init__.py +++ b/django/db/models/fields/__init__.py @@ -391,7 +391,7 @@ class Field(RegisterLookupMixin): from django.db.models.expressions import Value if ( - self.db_default is NOT_PROVIDED + not self.has_db_default() or ( isinstance(self.db_default, Value) or not hasattr(self.db_default, "resolve_expression") @@ -933,8 +933,7 @@ class Field(RegisterLookupMixin): def db_returning(self): """Private API intended only to be used by Django itself.""" return ( - self.db_default is not NOT_PROVIDED - and connection.features.can_return_columns_from_insert + self.has_db_default() and connection.features.can_return_columns_from_insert ) def set_attributes_from_name(self, name): @@ -1016,6 +1015,10 @@ class Field(RegisterLookupMixin): """Return a boolean of whether this field has a default value.""" return self.default is not NOT_PROVIDED + def has_db_default(self): + """Return a boolean of whether this field has a db_default value.""" + return self.db_default is not NOT_PROVIDED + def get_default(self): """Return the default value for this field.""" return self._get_default() @@ -1027,7 +1030,7 @@ class Field(RegisterLookupMixin): return self.default return lambda: self.default - if self.db_default is not NOT_PROVIDED: + if self.has_db_default(): from django.db.models.expressions import DatabaseDefault return lambda: DatabaseDefault( @@ -1045,9 +1048,7 @@ class Field(RegisterLookupMixin): @cached_property def _db_default_expression(self): db_default = self.db_default - if db_default is not NOT_PROVIDED and not hasattr( - db_default, "resolve_expression" - ): + if self.has_db_default() and not hasattr(db_default, "resolve_expression"): from django.db.models.expressions import Value db_default = Value(db_default, self)