mirror of
https://github.com/django/django.git
synced 2024-12-23 01:25:58 +00:00
Added Model.has_db_default() to encapsulate NOT_PROVIDED checks.
This avoids many awkward checks against NOT_PROVIDED and provides symmetry with Field.has_default() which is also the reason why it wasn't made a property.
This commit is contained in:
parent
e165c6ef09
commit
e197a2b222
@ -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:
|
||||
|
@ -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)
|
||||
|
@ -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:
|
||||
|
@ -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()
|
||||
|
@ -1117,10 +1117,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.
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user