Opened 6 years ago

Last modified 4 days ago

#11390 new Bug

If you use a callable as default value on a model field, it gets called 3 times.

Reported by: espen.nettbruk@… Owned by: nobody
Component: Forms Version: 1.0
Severity: Normal Keywords: models
Cc: danny.adair@… Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

I belive i found a bug in the Django code, im truly sorry if it isnt. I just added a callable (a function) as the default value to a models field. And when i then initate the model, e.x by refreshing the admin edit page, I can se that the function runs three (3) times. There is no reason this should happen and it could lead to performance issues if the calulations done in this function is though.

Change History (7)

comment:1 Changed 6 years ago by russellm

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Triage Stage changed from Unreviewed to Accepted

I've verified that this is actually happening. Without digging into details, I'm pretty sure the three calls are caused by:

  1. Instantiating an empty Model() instance to pass to the form
  2. Rendering the visible form field, and therefore the value displayed
  3. Rendering the hidden form field providing a comparison initial-value.

It might be possible to collapse these calls into a single usage, but it will take some spelunking to sort out the details. In the meantime, the workaround is to keep your default callables lightweight (or, if they can't be lightweight, cache the computed values).

comment:2 Changed 4 years ago by julien

  • Severity set to Normal
  • Type set to Bug

comment:3 Changed 3 years ago by aaugustin

  • UI/UX unset

Change UI/UX from NULL to False.

comment:4 Changed 3 years ago by aaugustin

  • Easy pickings unset

Change Easy pickings from NULL to False.

comment:5 Changed 3 years ago by danny.adair@…

  • Cc danny.adair@… added

I would like to add that this not just a performance issue.
I believe it prevents any kind of reliable "counter" fields, includig an IntegerField primary key where some control is needed (i.e. not just autoincrement). See http://stackoverflow.com/a/9354703/640759 (postgresql-only solution)
Another example would be per-foreignkey counters, such as invoice numbers which increase per customer account. A workaround there would be to postpone the pulling of a new counter number until save(). See http://djangosnippets.org/snippets/1574/

comment:6 Changed 2 years ago by aaugustin

  • Component changed from Core (Other) to Forms

comment:7 Changed 4 days ago by jdunck

Possibly fixed in #24391

Note: See TracTickets for help on using tickets.
Back to Top