Opened 4 months ago

Closed 4 months ago

Last modified 3 months ago

#35657 closed Bug (fixed)

Specifying db_default on FileField causes crash on instance save

Reported by: David Sanders Owned by: Sarah Boyce
Component: Database layer (models, ORM) Version: 5.0
Severity: Release blocker Keywords: db_default
Cc: Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

I guess there's the existential question: "Does db_default make sense with FileField/ImageField?" Perhaps, as long as there's a file at the path defined by the db_default expression? 🤔

In any case when defined with a FileField, the presence of DatabaseDefault as the field's value causes a crash:

Given the model:

class Foo(models.Model):
    bar = models.FileField(db_default="path/to/file.txt")

We get AttributeError exceptions when attempting to create an instance:

>>> Foo.objects.create()
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/path/to/django/django/db/models/manager.py", line 87, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/path/to/django/django/db/models/query.py", line 660, in create
    obj.save(force_insert=True, using=self.db)
  File "/path/to/django/django/db/models/base.py", line 891, in save
    self.save_base(
  File "/path/to/django/django/db/models/base.py", line 997, in save_base
    updated = self._save_table(
              ^^^^^^^^^^^^^^^^^
  File "/path/to/django/django/db/models/base.py", line 1160, in _save_table
    results = self._do_insert(
              ^^^^^^^^^^^^^^^^
  File "/path/to/django/django/db/models/base.py", line 1201, in _do_insert
    return manager._insert(
           ^^^^^^^^^^^^^^^^
  File "/path/to/django/django/db/models/manager.py", line 87, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/path/to/django/django/db/models/query.py", line 1828, in _insert
    return query.get_compiler(using=using).execute_sql(returning_fields)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/path/to/django/django/db/models/sql/compiler.py", line 1847, in execute_sql
    for sql, params in self.as_sql():
                       ^^^^^^^^^^^^^
  File "/path/to/django/django/db/models/sql/compiler.py", line 1770, in as_sql
    value_rows = [
                 ^
  File "/path/to/django/django/db/models/sql/compiler.py", line 1771, in <listcomp>
    [
  File "/path/to/django/django/db/models/sql/compiler.py", line 1772, in <listcomp>
    self.prepare_value(field, self.pre_save_val(field, obj))
                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/path/to/django/django/db/models/sql/compiler.py", line 1720, in pre_save_val
    return field.pre_save(obj, add=True)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/path/to/django/django/db/models/fields/files.py", line 320, in pre_save
    if file.name is None and file._file is not None:
       ^^^^^^^^^
AttributeError: 'DatabaseDefault' object has no attribute 'name'

Change History (12)

comment:1 by David Sanders, 4 months ago

Summary: Specifying db_default on FileField crashesSpecifying db_default on FileField causes crash on instance save

comment:2 by Sarah Boyce, 4 months ago

Has patch: set
Owner: set to Sarah Boyce
Severity: NormalRelease blocker
Status: newassigned
Triage Stage: UnreviewedAccepted

I feel like the behavior should mimic default here - accepting

comment:3 by Sarah Boyce, 4 months ago

Patch needs improvement: set

comment:4 by Sarah Boyce, 4 months ago

Has patch: unset
Owner: Sarah Boyce removed
Patch needs improvement: unset
Status: assignednew

comment:5 by Mohammad Salehi, 4 months ago

Hi, I tested this issue and it indeed exists. It can be resolved by initiating self.name to None in init, and that's it
I would send a PR to address this alongside a test, if you are ok.

in reply to:  5 comment:6 by Sarah Boyce, 4 months ago

Replying to Mohammad Salehi:

Hi, I tested this issue and it indeed exists. It can be resolved by initiating self.name to None in init, and that's it
I would send a PR to address this alongside a test, if you are ok.

That doesn't sound right
I've opened a PR

comment:7 by Sarah Boyce, 4 months ago

Owner: set to Sarah Boyce
Status: newassigned

comment:8 by Sarah Boyce, 4 months ago

Has patch: set

comment:9 by Natalia Bidart, 4 months ago

Triage Stage: AcceptedReady for checkin

comment:10 by GitHub <noreply@…>, 4 months ago

Resolution: fixed
Status: assignedclosed

In 8deb6bb1:

Fixed #35657 -- Made FileField handle db_default values.

comment:11 by Natalia <124304+nessita@…>, 4 months ago

In 2ba4f4b0:

[5.1.x] Fixed #35657 -- Made FileField handle db_default values.

Backport of 8deb6bb1fc427762d56646bf7306cbd11fb5bb68 from main.

comment:12 by Natalia <124304+nessita@…>, 4 months ago

In d7f9554:

[5.0.x] Fixed #35657 -- Made FileField handle db_default values.

Backport of 8deb6bb1fc427762d56646bf7306cbd11fb5bb68 from main.

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