Reputation: 4054
When I do python manage.py makemigrations
, i get above error and I am unsure where the error is happening. I saw some post regarding this issue but i find mainly in DateTimeField()
where the function was passed but in my case I have used auto_now
attribute instead of some datetime related function.
However, I have used lambda function in the class method as follow.
@classmethod
def get_content_models(cls):
"""
Return all Package subclasses.
"""
is_content_model = lambda m: m is not Package and issubclass(m, Package)
def set_helpers(self, context):
current_package_id = getattr(current_package, "id", None)
current_parent_id = getattr(current_package, "parent_id", None)
self.is_current_child = self.parent_id == current_package_id
self.is_child = self.is_current_child
def is_c_or_a(package_id):
parent_id = context.get("_parent_package_ids", {}).get(package_id)
return self.id == package_id or (parent_id and is_c_or_a(parent_id))
self.is_current_or_ascendant = lambda: bool(is_c_or_a(current_package_id))
I am not clear on this issue, So i have posted for understanding the cause. Is above code creating that issue? If it is the cause, what should be done instead?
I don't know where exactly this issue lies in the models so here is the detail of models.py of package app
in gist because the code is a bit huge . It is not reached to booking models so I am only putting the code of package app and here it is
https://gist.github.com/SanskarSans/51d2f287309a97163e680cc38abd3e06
UPDATE
In my Package models, I have used the custom field and in that field there was the use of lambda instead of callable function and that was creating an issue. Due to the long file of models, I did not paste it here, I apologize for that.
Here what I had done
in_menus = MenusField(_("Show in menus"), blank=True, null=True)
class MenusField(MultiChoiceField):
"""
``MultiChoiceField`` for specifying which menus a package should
appear in.
"""
def __init__(self, *args, **kwargs):
choices = [t[:2] for t in getattr(settings, "PAGE_MENU_TEMPLATES", [])]
default = getattr(settings, "PAGE_MENU_TEMPLATES_DEFAULT", None)
if default is None:
default = [t[0] for t in choices]
elif not default:
default = None
if isinstance(default, (tuple, list)):
d = tuple(default)
# this lambda should be avoided
# default = lambda:d
default = default_value(d)
defaults = {"max_length": 100, "choices": choices, "default": default}
defaults.update(kwargs)
super(MenusField, self).__init__(*args, **defaults)
Upvotes: 8
Views: 2707
Reputation: 3318
The follows might be helpful to others in the future.
It worked to change the lambda
expression into a function
.
The following square_root
and square_root_lambda
worked the same:
def square_root(x):
return math.sqrt(x)
square_root_lambda = lambda x: math.sqrt(x)
print(square_root(4))
print(square_root_lambda(4))
Upvotes: 0
Reputation: 24089
An example replacing the lambda
with a function.
Borken version:
class SomeModel(ParentModel):
thing_to_export = ArrayField(models.CharField(max_length=50),
default=lambda: ['Default thing'])
Working version:
def default_thing():
return ['THIS IS A DEFAULT']
class SomeModel(ParentModel):
thing_to_export = ArrayField(models.CharField(max_length=50),
default=default_thing)
Upvotes: 2
Reputation: 10906
I assume you are using the pickle module for serialization.
You cannot pickle the class in which set_helpers
is defined. That method sets self.is_current_or_ascendant
to a lambda function, and those are on the list of things that cannot be pickled (see 12.1.4 in https://docs.python.org/3/library/pickle.html).
The class method cannot be a problem since it only defines one local variable, is_content_model
, which immediately goes out of scope and gets deleted. In fact that method, as you presented it here, does nothing at all.
Upvotes: 0