Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django model fields: reference to self on default keyword

I've been having problems to understand this and to come up with a way of doing a reference to self inside the default keyword of a model field:

Here is what I have:

class Bank(models.Model):
    number = models.CharField(max_length=10)

class Account(models.Model):
    bank = models.ForeignKey(Bank, related_name="accounts")
    number = models.CharField(max_length=20)
    created = models.DateTimeField(auto_now_add=True)
    creator = models.ForeignKey(User)
    # This is the guy
    special_code = models.CharField(max_length=30, default='%s-%s' % (self.number, self.bank.number))

So I'm trying to access self inside the class definition, which seems to not work out because python doesn't know where self is since its not an object yet.

I've tried different things like:

special_code = models.CharField(max_length=30, default='%s-%s' % (number, bank.number))

But in this case it doesn't recognize bank.number because bank its only a property with models.ForeignKey.

I've tried also using a method inside the Account class:

def bank_number(self):
    return self.bank.number

and then:

special_code = models.CharField(max_length=30, default='%s-%s' % (number, bank_number()))

That was kinda dumb because it still needs self. Is there a way I can do this?

I need it to store the number inside the database, so using a method like this wont help:

def special_number(self):
    return '%s-%s' % (self.number, self.bank.number)
like image 798
Guilherme David da Costa Avatar asked Dec 20 '22 13:12

Guilherme David da Costa


2 Answers

I don't think there's any way to access self in the default callable. There's a couple of other approaches to set your field's value:

If you don't want the user to be able to change the value, override the model's save method and set it there.

If the default is just a suggestion, and you do want to allow the user to change it, then override the model form's __init__ method, then you can access self.instance and change set the field's initial value.

like image 88
Alasdair Avatar answered Feb 02 '23 05:02

Alasdair


Instead of specifying a default for the field you probably want to override the save() method and populate the field right before storing the object in the database. The save() method also has access to self. Here is an example in the docs for that:

https://docs.djangoproject.com/en/dev/topics/db/models/#overriding-model-methods

like image 29
Viorel Avatar answered Feb 02 '23 04:02

Viorel