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