Thanks for the quick response Lily
I just realised that setting the value to DatabaseDefault()
now syncs up nicely with this patch for a model鈥檚 full clean: Fixed #35223 -- Made Model.full_clean() ignore fields with db_default when validating empty values. by bcail 路 Pull Request #17939 路 django/django 路 GitHub
There is one last thing that is blocking me from delegating to the default though - during a full clean validation of constraints is included and I have a check constraint on this particular field that is now failing because the select statement doesn鈥檛 know what DEFAULT
means.
I couldn鈥檛 see how to workaround this in my code but altering Django to refer to the underlying expression instead during Q.check()
seems to work:
(Note this isn鈥檛 ideal as the supplied DatabaseDefault
ends up being wrapped in a Value
by Model._get_field_value_map()
.)
I might raise a separate follow-up ticket to #35223
Edit I realise doing value.value
below will cause exceptions, but this is just for demonstrative purposes
index 1bf396723e..4238397de2 100644
--- a/django/db/models/query_utils.py
+++ b/django/db/models/query_utils.py
@@ -120,12 +120,16 @@ class Q(tree.Node):
"""
# Avoid circular imports.
from django.db.models import BooleanField, Value
+ from django.db.models.expressions import DatabaseDefault
from django.db.models.functions import Coalesce
from django.db.models.sql import Query
from django.db.models.sql.constants import SINGLE
+
query = Query(None)
for name, value in against.items():
+ if isinstance(value.value, DatabaseDefault):
+ value = value.field.db_default
if not hasattr(value, "resolve_expression"):
value = Value(value)
query.add_annotation(value, name, select=False)