Reputation: 3650
I am using PyCharm 4.5.2, Django 1.8.2.
If I define a class as:
class User(models.Model):
first_name = models.CharField(max_length=256)
last_name = models.CharField(max_length=256)
slug = models.SlugField(max_length=256, unique=True, default=make_slug)
def make_slug(self):
return self.first_name + self.last_name[0]
The IDE highlights default=make_slug
with make_slug
being undefined. The interpretter agrees and when the development server tries to refresh it exits with status 1
and the error NameError: name 'make_slug' is not defined.
Because it's just the name of a callable, I can't pass arguments. So if I define the function outside the class (to move into a higher scope and be defined) I can't use the class properties. I have read some suggestions that use lambdas but from the Django documentation that is wrong:
Note that lambdas cannot be used for field options like default because they cannot be serialized by migrations. See that documentation for other caveats.
What is the proper way to define a callable for default values in a model.
Upvotes: 2
Views: 785
Reputation: 309099
You get this error
NameError: name 'make_slug' is not defined.
because you refer to make_slug
before you defined it. If you moved the make_slug
function above the slug
field, then you wouldn't get that error.
However, it isn't possible to pass any arguments to the callable that you use as the default, so that won't work either. You can't get around that restriction by using a model method as you are trying.
If you need access to the model instance to calculate the default, then setting the value in the save()
method as ruddra suggests is a good idea. Note that you might want to check whether or not the model has a primary key, so that you only create the slug when you first create the instance.
Upvotes: 1
Reputation: 52028
You shouldn't use this method to set your default value, rather than override the save method of the model and use it there. For example:
class User(models.Model):
first_name = models.CharField(max_length=256)
last_name = models.CharField(max_length=256)
slug = models.SlugField(max_length=256, unique=True, default=uuid.uuid1)
def make_slug(self):
return self.first_name + self.last_name[0]
def save(self, *args, **kwargs):
self.slug = self.make_slug()
super().save(*args, **kwargs)
Upvotes: 2