#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:

> 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.

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!__:

 {{{
         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#comment:1>
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 django-updates+unsubscr...@googlegroups.com.
To post to this group, send email to django-updates@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/062.83967dd8e438761d48bc5e05caba170c%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to