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
I 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?
str function in a django model returns a string that is exactly rendered as the display name of instances for that model. # Create your models here. This will display the objects as something always in the admin interface.
default: The default value for the field. This can be a value or a callable object, in which case the object will be called every time a new record is created. null: If True , Django will store blank values as NULL in the database for fields where this is appropriate (a CharField will instead store an empty string).
save() method from its parent class is to be overridden so we use super keyword. slugify is a function that converts any string into a slug. so we are converting the title to form a slug basically.
The doc says: If the object's primary key attribute is set to a value that evaluates to True (i.e. a value other than None or the empty string), Django executes an UPDATE. If the object's primary key attribute is not set or if the UPDATE didn't update anything, Django executes an INSERT link.
In your examples, you need to remove the call operator ()
.
Currently the statement is executed immediately at the first read-parsing cycle. By specifying the symbol name instead, the Django class receives a function pointer which it will execute when it actually needs the default value.
The example becomes:
def get_previous(): return ModelA.objects.all()[0].fieldA class ModelA(models.Model): fieldA = models.CharField(default=get_previous)
If you're going to do this for a lot of fields, consider overridding the save
function, so you only have to fetch the previous object from the database just once.
If you want to just output default value, override __getattr__()
method like this:
class ModelA(models.Model): # your fields def __getattr__(self, name): if(name == 'fieldA' and !self.fieldA): return self.get_previous() else: return super(ModelA, self).__getattr__(name)
Saving default value from object will be little difficultier. First solution that comes in my mind, override save()
method (i believe there is simpler solution)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With