gintare
gintare

Reputation: 21

Result of database query as default value for Django model field?

models.py

class Aref5(models.Model):
    name = Aref5.objects.all.order_by('id')[0]
    Rthink = models.TextField(max_length=2000,  blank=True, default=name)
    <....>

I would like to have the default value of Rthink be the id of the the last item.

With the above code I get an error saying that Aref5 is not recognized. How can I access existing Aref5 instances within the definition of Aref5?

Upvotes: 2

Views: 2455

Answers (2)

pyjavo
pyjavo

Reputation: 1613

According to the recent documentation for the default value This can be a value or a callable object. If callable it will be called every time a new object is created.

The default can’t be a mutable object (model instance, list, set, etc.), as a reference to the same instance of that object would be used as the default value in all new model instances. Instead, wrap the desired default in a callable.

Example:

def contact_default():
    return {"email": "[email protected]"}

contact_info = JSONField("ContactInfo", default=contact_default)

lambdas can’t be used for field options like default because they can’t be serialized by migrations

Upvotes: 0

Ismail Badawi
Ismail Badawi

Reputation: 37177

There are a couple of problems here. One is that if this were to work, name would be computed once whenever Django started up, and every instance of Aref5 would get the same default value. The other is that trying to access a class within its definition causes an error.

The default argument to a TextField (or any Field subclass) can be a callable instead of a value, in which case it will be called whenever a new object is created. Something like this should work:

Rthink = models.TextField(max_length=2000, blank=True, default=lambda: str(Aref5.objects.latest('id').id))

Since the expression involving Aref5 appears inside a function body, it's not evaluated right away.

Upvotes: 3

Related Questions