26 lines
1.2 KiB
Diff
26 lines
1.2 KiB
Diff
# UNDF: UNDF-2026-000000047
|
||
Fixes django-0001: Model.from_db() — field_names list membership test inside concrete_fields loop.
|
||
|
||
--- a/django/db/models/base.py
|
||
+++ b/django/db/models/base.py
|
||
|
||
@@ DEFECT django-0001: Model.from_db() lines 618-624
|
||
|
||
@classmethod
|
||
def from_db(cls, db, field_names, values, *, fetch_mode=None):
|
||
if len(values) != len(cls._meta.concrete_fields):
|
||
values_iter = iter(values)
|
||
+ field_names_set = set(field_names) # FIX django-0001: O(F) once; was O(1) per loop
|
||
values = [
|
||
- next(values_iter) if f.attname in field_names else DEFERRED # O(F) list scan — CWE-407
|
||
+ next(values_iter) if f.attname in field_names_set else DEFERRED # O(1) — fixed
|
||
for f in cls._meta.concrete_fields
|
||
]
|
||
|
||
# BEFORE: field_names is a list; `f.attname in field_names` is O(F) per field.
|
||
# Called once per queryset row in ModelIterable.__iter__.
|
||
# Total for N rows × F fields: O(N × F²).
|
||
# AFTER: field_names_set is a frozenset; O(1) per field.
|
||
# Total: O(N × F).
|
||
# Triggered by: QuerySet.defer(), .only() — the primary Django ORM optimization APIs.
|
||
# ~50× speedup for a 50-field model.
|