Creating default id in Django from function string and prefix
What I need to do is run the function and add a prefix to the beginning of the results returned by that function. This needs to be done every time a new instance of my model is created.
What I have tried ....
The following will not work because you cannot add a line to the function and set the ID as s_<function name etc>
, not the results of the function.
APP_PREFIX = "_s"
id = models.CharField(primary_key=True, max_length=50, unique=True,
default="{}{}".format(APP_PREFIX, make_id))
And it won't pass the prefix to the function, because Django will generate the same key every time the function is called this way, dont know why tho:
id = models.CharField(primary_key=True, max_length=50, unique=True,
default=make_id(APP_PREFIX))
This won't work either:
id = models.CharField(primary_key=True, max_length=50, unique=True,
default=make_id + APP_PREFIX)
Or that:
id = models.CharField(primary_key=True, max_length=50, unique=True,
default=make_id() + APP_PREFIX)
How can this be achieved?
I could overwrite the method save()
and achieve this, but there must be a way to do it with a default parameter in the field!
source to share
You can create your own manager for your model and override the method create()
. Then in the method, create()
you can generate the ID field by explicitly calling the function make_id
. The only thing is that you shouldn't set a default property for the id field.
So, the model will look something like this:
class MyModel(models.Model):
id = models.CharField(primary_key=True, max_length=50, unique=True)
objects = MyModelManager()
Then the implementation MyModelManager
should look something like this:
class MyModelManager(models.Manager):
def create(self, **kwargs):
kwargs['id'] = make_id()
return super(MyModelManager, self).create(**kwargs)
Of course, you must add any other parameters to the create method as needed to instantiate your model.
Object instantiation is MyModel
done as follows:
my_model = MyModel.objects.create()
Alternatively, if you want to use the default property, the following should work for you:
class MyModel(models.Model):
APP_PREFIX = "_s"
id = models.CharField(primary_key=True, max_length=50, unique=True,
default=lambda: generate_id(MyModel.APP_PREFIX))
def generate_id(prefix):
return make_id() + prefix
source to share
Method rewriting save
should be easy to implement:
from django.db import models
class YourModel(models.Model):
id = models.CharField(primary_key=True, max_length=50, unique=True)
# other fields for YourModel
def make_id():
return base64.b64encode(uuid.uuid4().bytes).decode("utf-8")
def save(self, *args, ***kwargs):
if not self.id:
self.id = self.make_id()
super(YourModel, self).save(*args, **kwargs)
make_id
Not a method after all YourModel
, but it's just a small change in the code. In the method, save
you can combine "s_" or whatever you need. The ID is only generated if the record does not have an ID (which does not exist yet).
Using self.pk
might be an alternative (and possibly) better approach. You can omit explicit field creation id
.
source to share