Django: field's default value from self model's instances

Viewed 17510

How can I make default value for a field to be taken from existing objects of a model?

I tried these and it didn't worked:

1)

class ModelA(models.Model):
    fieldA = models.CharField(default=self.get_previous())
    
    def get_previous(self):
        return ModelA.objects.all()[0].fieldA

NameError: name 'self' is not defined

2)

class ModelA(models.Model):
    fieldA = models.CharField(default=ModelA.get_previous())

    @staticmethod
    def get_previous():
        return ModelA.objects.all()[0].fieldA

NameError: name 'ModelA' is not defined

3)

class ModelA(models.Model):
    fieldA = models.CharField(default=get_previous())

def get_previous():
    return ModelA.objects.all()[0].fieldA

NameError: global name 'get_previous' is not defined

4)

def get_previous():
    return ModelA.objects.all()[0].fieldA

class ModelA(models.Model):
    fieldA = models.CharField(default=get_previous())

NameError: global name 'ModelA' is not defined

It's clear why 3) and 4) won't work. I can imagine why 1) won't work - looks like class' properies can't refer to instance's (i.e. self). I can imagine why 2) won't work - apparently there's no reference to ModelA until interpreter will go trough whole class.

So how should I approach this?

4 Answers

"get_previous" works:

                                  # Here
fieldA = models.CharField(default=get_previous)

But "get_previous()" doesn't work:

                                  # Here
fieldA = models.CharField(default=get_previous())

In addition, your code is lacking Exception Handling so I added it to your code as shown below:

def get_previous():
    try:
        return ModelA.objects.all()[0].fieldA
    except IndexError:
        return None

class ModelA(models.Model):
    fieldA = models.CharField(default=get_previous)

You can also use this code below. first() returns the first object, or None if there are no objects:

def get_previous():
    try:                           # Here
        return ModelA.objects.all().first().fieldA
    except AttributeError:
        return None

class ModelA(models.Model):
    fieldA = models.CharField(default=get_previous)
Related