#35731: Fields with db_default, and without default, are initialized to 
instance of
DatabaseDefault
-------------------------------------+-------------------------------------
     Reporter:  kylebebak            |                     Type:
                                     |  Cleanup/optimization
       Status:  new                  |                Component:  Database
                                     |  layer (models, ORM)
      Version:  5.0                  |                 Severity:  Normal
     Keywords:                       |             Triage Stage:
                                     |  Unreviewed
    Has patch:  0                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  0
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+-------------------------------------
 For example, if client code creates a model `Foo` with `val =
 IntegerField(db_default=10)`, does `foo = Foo()`, and accesses `foo.val`,
 they get an instance of `django.db.models.expressions.DatabaseDefault`.

 This `DatabaseDefault` seems to be used for bookkeeping until the model
 instance is written to the DB, after which `foo.val` is an `int`. IMO this
 is not a good design, because it's a case of an implementation detail
 (setting a value for the field once it's saved to the DB) changing the
 model's public interface (IMO a model instance's field values are part of
 its public interface).

 If instead we do `val = IntegerField()`, and `foo = Foo()`, and access
 `foo.val`, we get `None`, s.t. the type of `foo.val` is `int | None`.
 Using `db_default` means that the type of `foo.val` is now `int |
 DatabaseDefault`. `DatabaseDefault` is a bookkeeping type that client code
 usually shouldn't interact with. If users aren't aware of `db_default`'s
 implementation, they might still write code like this, which would be
 broken: `if foo.val is not None: print(foo.val + 10)`.

 Because `DatabaseDefault` is for bookkeeping, it seems like there's no
 reason the model instance couldn't store its `DatabaseDefault` instances
 on a "private" field which wouldn't affect the model's public interface.
 This would be a lot cleaner IMO. Most users shouldn't know about
 `DatabaseDefault`, which unsurprisingly isn't mentioned here,
 https://docs.djangoproject.com/en/5.1/ref/models/fields/#db-default, or
 anywhere else in the docs AFAICT.
-- 
Ticket URL: <https://code.djangoproject.com/ticket/35731>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/01070191bf6af9a2-1fe4918b-d1ce-4b6b-95a0-037d549e94e1-000000%40eu-central-1.amazonses.com.

Reply via email to