简体   繁体   中英

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)

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.

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

As already answered, override the save() method of your model to assign a value to special_code . The default option of a field is not meant to depend on other fields of the model, so this will not work.

Also, have a look at the editable option, if you don't want the field to be edited.

special_code = models.CharField(max_length=30, editable=False)

Will prevent the field to be rendered in ModelForms you create from the model.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM