﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
28188	Field._get_default() prevents model fields from being pickled	Adam Alton	GitHub <noreply@…>	"The changes introduced in [[https://github.com/django/django/commit/d2a26c1a90e837777dabdf3d67ceec4d2a70fb86#diff-bf776a3b8e5dbfac2432015825ef8afe|d2a26c1a90e837777dabdf3d67ceec4d2a70fb86]] mean that in cases where a model field has a default and the default is not a callable, the field instance cannot be pickled.

The offending line is:

{{{#!python
  return lambda: self.default
}}}

This problem only exists in Django version >= 1.11.

The reason for that ''lambda'' is because the code has been refactored so that all the logic for getting the default value has been moved into the ''_get_default'' method, which allows it to be cached with the ''@cached_property'' decorator.  And then the ''get_default'' method expects the value returned from ''_get_default'' to always be a callable.  That requirement for the value to always be a callable is the reason for wrapping the value with ''lambda'' in the case where it's not already a callable.

My proposed solution is to simply move the ''if callable()'' check back out into the ''get_default'' method.  This would mean that we lose a very minor bit of efficiency because we have to run that one ''if'' statement each time that ''get_default'' is called, but the rest of the logic would remain inside the cached ''_get_default'' method.

I have made a commit here which contains my proposed fix and a test to prevent regression: https://github.com/adamalton/django/commit/ee6aafacfd01f2603943e8c4183805fd4a298355

"	Bug	closed	Database layer (models, ORM)	1.11	Release blocker	fixed			Accepted	1	0	0	0	0	0
