[Django] #24823: FileField with callable default raise error with forms

8 views
Skip to first unread message

Django

unread,
May 19, 2015, 8:24:48 PM5/19/15
to django-...@googlegroups.com
#24823: FileField with callable default raise error with forms
-------------------------------------+-------------------------------------
Reporter: ymph | Owner: nobody
Type: Bug | Status: new
Component: Database layer | Version: 1.8
(models, ORM) | Keywords: FileField, models,
Severity: Normal | field
Triage Stage: Unreviewed | Has patch: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Hello,

When a FileField has a callable default value, the following error is
raised when a new object is created using a form and no value is provided
for the field:

`'function' object has no attribute '_committed' in
db/models/fields/files.py in pre_save, line 316`

This bug can be reproduced with the content of the following gist :
https://gist.github.com/ymph/cd2b684f3f2f38a680d5 and by following the
instruction in the README.

The problem does not appear when creating the object without forms.

I was able to naively "correct" the problem by adding the following lines
in the file db/models/fields/files.py, line 194 in FieldFile.!__get!__:

{{{
if callable(file):
file = file()
}}}

here is a complete traceback:
{{{
Environment:


Request Method: POST
Request URL: http://localhost:8000/admin/testdefault/testobject/add/

Django Version: 1.8.1
Python Version: 2.7.6
Installed Applications:
('django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'testdefault')
Installed Middleware:
('django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.security.SecurityMiddleware')


Traceback:
File "/Users/ymh/dev/venvs/testdefault/lib/python2.7/site-
packages/django/core/handlers/base.py" in get_response
132. response = wrapped_callback(request,
*callback_args, **callback_kwargs)
File "/Users/ymh/dev/venvs/testdefault/lib/python2.7/site-
packages/django/contrib/admin/options.py" in wrapper
616. return self.admin_site.admin_view(view)(*args,
**kwargs)
File "/Users/ymh/dev/venvs/testdefault/lib/python2.7/site-
packages/django/utils/decorators.py" in _wrapped_view
110. response = view_func(request, *args, **kwargs)
File "/Users/ymh/dev/venvs/testdefault/lib/python2.7/site-
packages/django/views/decorators/cache.py" in _wrapped_view_func
57. response = view_func(request, *args, **kwargs)
File "/Users/ymh/dev/venvs/testdefault/lib/python2.7/site-
packages/django/contrib/admin/sites.py" in inner
233. return view(request, *args, **kwargs)
File "/Users/ymh/dev/venvs/testdefault/lib/python2.7/site-
packages/django/contrib/admin/options.py" in add_view
1516. return self.changeform_view(request, None, form_url,
extra_context)
File "/Users/ymh/dev/venvs/testdefault/lib/python2.7/site-
packages/django/utils/decorators.py" in _wrapper
34. return bound_func(*args, **kwargs)
File "/Users/ymh/dev/venvs/testdefault/lib/python2.7/site-
packages/django/utils/decorators.py" in _wrapped_view
110. response = view_func(request, *args, **kwargs)
File "/Users/ymh/dev/venvs/testdefault/lib/python2.7/site-
packages/django/utils/decorators.py" in bound_func
30. return func.__get__(self, type(self))(*args2,
**kwargs2)
File "/Users/ymh/dev/venvs/testdefault/lib/python2.7/site-
packages/django/utils/decorators.py" in inner
145. return func(*args, **kwargs)
File "/Users/ymh/dev/venvs/testdefault/lib/python2.7/site-
packages/django/contrib/admin/options.py" in changeform_view
1467. self.save_model(request, new_object, form, not
add)
File "/Users/ymh/dev/venvs/testdefault/lib/python2.7/site-
packages/django/contrib/admin/options.py" in save_model
1078. obj.save()
File "/Users/ymh/dev/venvs/testdefault/lib/python2.7/site-
packages/django/db/models/base.py" in save
710. force_update=force_update,
update_fields=update_fields)
File "/Users/ymh/dev/venvs/testdefault/lib/python2.7/site-
packages/django/db/models/base.py" in save_base
738. updated = self._save_table(raw, cls, force_insert,
force_update, using, update_fields)
File "/Users/ymh/dev/venvs/testdefault/lib/python2.7/site-
packages/django/db/models/base.py" in _save_table
822. result = self._do_insert(cls._base_manager, using,
fields, update_pk, raw)
File "/Users/ymh/dev/venvs/testdefault/lib/python2.7/site-
packages/django/db/models/base.py" in _do_insert
861. using=using, raw=raw)
File "/Users/ymh/dev/venvs/testdefault/lib/python2.7/site-
packages/django/db/models/manager.py" in manager_method
127. return getattr(self.get_queryset(), name)(*args,
**kwargs)
File "/Users/ymh/dev/venvs/testdefault/lib/python2.7/site-
packages/django/db/models/query.py" in _insert
920. return
query.get_compiler(using=using).execute_sql(return_id)
File "/Users/ymh/dev/venvs/testdefault/lib/python2.7/site-
packages/django/db/models/sql/compiler.py" in execute_sql
970. for sql, params in self.as_sql():
File "/Users/ymh/dev/venvs/testdefault/lib/python2.7/site-
packages/django/db/models/sql/compiler.py" in as_sql
928. for obj in self.query.objs
File "/Users/ymh/dev/venvs/testdefault/lib/python2.7/site-
packages/django/db/models/fields/files.py" in pre_save
316. if file and not file._committed:

Exception Type: AttributeError at /admin/testdefault/testobject/add/
Exception Value: 'function' object has no attribute '_committed'
}}}

regards.

--
Ticket URL: <https://code.djangoproject.com/ticket/24823>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
May 19, 2015, 8:31:27 PM5/19/15
to django-...@googlegroups.com
#24823: FileField with callable default raise error with forms
-------------------------------------+-------------------------------------
Reporter: ymph | Owner: nobody
Type: Bug | Status: new
Component: Database layer | Version: 1.8
(models, ORM) |
Severity: Normal | Resolution:
Keywords: FileField, models, | Triage Stage:
field | Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by ymph):

* needs_better_patch: => 0
* needs_tests: => 0
* needs_docs: => 0


Old description:

New description:

Hello,

When a FileField has a callable default value, the following error is
raised when a new object is created using a form and no value is provided
for the field:

`'function' object has no attribute '_committed' in
db/models/fields/files.py in pre_save, line 316`

This bug can be reproduced with the content of the following gist :
https://gist.github.com/ymph/cd2b684f3f2f38a680d5 and by following the
instruction in the README.

The problem does not appear when creating the object without forms.

I was able to naively "correct" the problem by adding the following lines
in the file db/models/fields/files.py, line 194 in

FileDescriptor.!__get!__:

regards.

--

--
Ticket URL: <https://code.djangoproject.com/ticket/24823#comment:1>

Django

unread,
May 20, 2015, 11:37:27 AM5/20/15
to django-...@googlegroups.com
#24823: FileField with callable default raise error with forms
-------------------------------------+-------------------------------------
Reporter: ymph | Owner: nobody
Type: Bug | Status: new
Component: Database layer | Version: 1.8
(models, ORM) |
Severity: Normal | Resolution:
Keywords: FileField, models, | Triage Stage:
field | Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by ymph):

Hello,

a attempt for a correction can be found in the branch ticket_24823 of my
fork : https://github.com/IRI-Research/django/tree/ticket_24823

regards,

ymph

--
Ticket URL: <https://code.djangoproject.com/ticket/24823#comment:2>

Django

unread,
May 20, 2015, 4:30:00 PM5/20/15
to django-...@googlegroups.com
#24823: FileField with callable default raise error with forms
-------------------------------------+-------------------------------------
Reporter: ymph | Owner: nobody
Type: Bug | Status: closed

Component: Database layer | Version: 1.8
(models, ORM) |
Severity: Normal | Resolution: needsinfo

Keywords: FileField, models, | Triage Stage:
field | Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by timgraham):

* status: new => closed
* resolution: => needsinfo


Comment:

Currently the behavior of how `default` should work on `FileField` isn't
well defined (see #17224). Let's address that one first and then reopen
this if we decide it makes sense to support this. By the way, any patch
should be against the master branch, as this wouldn't be backported to
1.8. Thanks!

--
Ticket URL: <https://code.djangoproject.com/ticket/24823#comment:3>

Django

unread,
Jun 23, 2017, 2:07:17 AM6/23/17
to django-...@googlegroups.com
#24823: FileField with callable default raise error with forms
-------------------------------------+-------------------------------------
Reporter: Haussonne Yves- | Owner: nobody
Marie |
Type: Bug | Status: closed

Component: Database layer | Version: 1.8
(models, ORM) |
Severity: Normal | Resolution: needsinfo
Keywords: FileField, models, | Triage Stage:
field | Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Tai Lee):

Just spent a few hours stepping through tracebacks trying to find out
exactly what Django is doing here, before coming to the conclusion that it
must be a Django bug and searching for an existing ticket.

Perhaps I haven't read the documentation recently or thoroughly enough,
but they don't seem that ambiguous regarding the behaviour of `default`
specifically:

{{{
The default value for the field. This can be a value or a callable object.
If callable it will be called every time a new object is created.
}}}

There's no special caveat for `FileField` and `ImageField` saying that
callables cannot be used.

Whether or not additional special handling of the evaluated default value
(as per discussion on #17224) is ever implemented, that should not make
any difference at all as to whether or not a callable can be used as a
default.

I think this ticket should be re-opened, and can and should be resolved
much quicker and simpler than #17224, without much debate?

It's valid to assign a string to a `FileField` (on an instance, or as a
default value). Is there any reason why a callable that returns a string
shouldn't be valid?

--
Ticket URL: <https://code.djangoproject.com/ticket/24823#comment:4>

Django

unread,
Jun 23, 2017, 2:07:39 AM6/23/17
to django-...@googlegroups.com
#24823: FileField with callable default raise error with forms
-------------------------------------+-------------------------------------
Reporter: Haussonne Yves- | Owner: nobody
Marie |
Type: Bug | Status: new
Component: Database layer | Version: 1.8
(models, ORM) |
Severity: Normal | Resolution:

Keywords: FileField, models, | Triage Stage:
field | Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Tai Lee):

* status: closed => new
* resolution: needsinfo =>


--
Ticket URL: <https://code.djangoproject.com/ticket/24823#comment:5>

Django

unread,
Jun 23, 2017, 2:16:03 AM6/23/17
to django-...@googlegroups.com
#24823: FileField with callable default raise error with forms
-------------------------------------+-------------------------------------
Reporter: Haussonne Yves- | Owner: nobody
Marie |
Type: Bug | Status: new
Component: Database layer | Version: 1.8
(models, ORM) |
Severity: Normal | Resolution:
Keywords: FileField, models, | Triage Stage:
field, callable, default, form | Unreviewed

Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Tai Lee):

* keywords: FileField, models, field => FileField, models, field,
callable, default, form


Comment:

Plus, the fact that this actually does work as expected for `FileField`
(models) is *only* broken with forms, makes the case stronger that this is
a clear bug. The forms docs even say (of `Field.initial`):

{{{
Instead of a constant, you can also pass any callable
}}}

And when we stepped through form cleaning, we noticed that form data *did*
contain a properly evaluated default as `initial-{fieldname}`, but the
field cleaning ignored it and assigned the raw callable from the model
instead.

--
Ticket URL: <https://code.djangoproject.com/ticket/24823#comment:6>

Django

unread,
Jun 23, 2017, 2:38:57 AM6/23/17
to django-...@googlegroups.com
#24823: FileField with callable default raise error with forms
-------------------------------------+-------------------------------------
Reporter: Haussonne Yves- | Owner: nobody
Marie |
Type: Bug | Status: new
Component: Database layer | Version: 1.8
(models, ORM) |
Severity: Normal | Resolution:
Keywords: FileField, models, | Triage Stage:
field, callable, default, form | Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Tai Lee):

* cc: real.human@… (added)


--
Ticket URL: <https://code.djangoproject.com/ticket/24823#comment:7>

Django

unread,
Jun 26, 2017, 11:19:23 AM6/26/17
to django-...@googlegroups.com
#24823: FileField with callable default raises error with forms
-------------------------------------+-------------------------------------

Reporter: Haussonne Yves- | Owner: nobody
Marie |
Type: Bug | Status: new
Component: Database layer | Version: 1.8
(models, ORM) |
Severity: Normal | Resolution:
Keywords: FileField, models, | Triage Stage: Accepted
field, callable, default, form |

Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Tim Graham):

* stage: Unreviewed => Accepted


--
Ticket URL: <https://code.djangoproject.com/ticket/24823#comment:8>

Reply all
Reply to author
Forward
0 new messages