Vlad Shlyanin
Vlad Shlyanin

Reputation: 57

Save model field value as default for another field

Here's a relevant code from my models.py file

class PhotoManager(models.Model):
     id = models.AutoField(primary_key=True)
     def model_instance_id(self):
         return self.id
     index = models.PositiveIntegerField(default = model_instance_id, blank=True, unique = False)

What I'm trying to do is to save model id field value into index field (to safely edit it later with AJAX calls to Django Rest Framework). As I understand, the only correct option to save model field value to another field is setting default value as a function. When I save model instance I get an error:

TypeError: model_instance_id() missing 1 required positional argument: 'self'

Anyway, I can't figure out, how to reference ID field in mentioned function.

I tried use save method, but it just does nothing

def save(self, *args, **kwargs):
     if not self.index:
         self.index = self.id
     super().save(*args, **kwargs)

Upvotes: 3

Views: 915

Answers (2)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476557

The problem is that you set the index before saving the instance, at that point, new model instance do not yet have an id. So you can perform two .save()s: one before obtaining the id, and one to save the new index.

def save(self, *args, **kwargs):
    if self.id is None:
        super().save(*args, **kwargs)
    if self.index is None:
        self.index = self.id
        super().save(*args, **kwargs)

But that being said, it is still not a good idea: there are various ways to circumvent the .save(..) method, for example when updating specific fields, etc.

Therefore I advice you to make a column _index instead that is NULL-able, and then write a @property to handle the case where the index is NULL:

class PhotoManager(models.Model):
    id = models.AutoField(primary_key=True)
    _index = models.PositiveIntegerField(null=True, default=None, blank=True)

    @property
    def index(self):
        if self._index is not None:
            return self._index
        return self.id

Upvotes: 3

Ali
Ali

Reputation: 2591

You should use parentheses, when calling function

index = models.PositiveIntegerField(default = model_instance_id(), blank=True, unique = False)

Upvotes: 0

Related Questions