Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating a default ID in Django from a function and prefix string

What I need to do is run a function and append a prefix to the beginning of the results returned from that function. This needs to be done each time a new instance is created of my model.

What I have tried....

The following won't work because you cannot add a string to a function and would set the ID as s_<function name etc> and 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))

Nor will passing the prefix to the function because Django will generate the same key each time calling the function this way, no idea 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 this:

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 save() method and achieve this but there must be a way to do this with the default parameter on the field!

like image 873
Prometheus Avatar asked May 28 '15 14:05

Prometheus


2 Answers

Rewriting the save method should be simple 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)

Eventually make_id is not a method of YourModel, but that is just a slight change in the code. In the method save you can concatenate "s_" or whatever you need. The id is generated only if the entry hasn't got any id (meaning it doesn't yet exist).

Using self.pk might be an alternative (and maybe) better approach. You could omit the explicit creation of the field id.

like image 29
cezar Avatar answered Sep 30 '22 12:09

cezar


I found a way to achieve this on my model:

PREFIX = settings.PREFIXES['THIS']
def get_id():
  return make_id(PREFIX)

    class MyModel(models.Model):
        id = models.CharField(primary_key=True,unique=True,
                                  default=get_id,)
like image 140
Prometheus Avatar answered Sep 30 '22 11:09

Prometheus