Proposal: To have db_default considered in model forms

Thanks for the quick response Lily :pray:

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. :thinking:

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 :sweat_smile:

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)