wraithie
wraithie

Reputation: 363

Django: Assign default value using model method (using self)

I'm looking to assign a default value using a method inside model:

class Discussion(models.Model):
    # attributes ...

    def __str__(self):
            return str(self.id) + ". " + self.title

    def class_name(self):
        return self.__class__.__name__

    discussion_type = models.CharField(max_length = 50, default = self.class_name())

class TechDiscussion(Discussion):
    # ...

class ScienceDiscussion(Discussion):
    # ...

In my Django app, users can only create science or tech discussions. Thus discussion_type should be either "TechDiscussion" or "ScienceDiscussion".

Server returns error NameError: name 'self' is not defined, referring to the default value assigned to discussion_type.

Upvotes: 0

Views: 335

Answers (2)

wraithie
wraithie

Reputation: 363

As Bear Brown suggested in the comment a solution would be to override the save() method of the Discussion class, also documented here. I removed the discussion_type assignment and added the override, as in the documentation:

class Discussion(models.Model):
    # attributes ...

    def __str__(self):
            return str(self.id) + ". " + self.title

    def class_name(self):
        return self.__class__.__name__

    def save(self, *args, **kwargs):
            self.call_type = self.class_name()
            super().save(*args, **kwargs)

Upvotes: 1

ger.s.brett
ger.s.brett

Reputation: 3308

This cannot work as the Discussion model will have its own database table - so you need to make it abstract. It will still try to access self where there is no object, so replace this with the class name. And it shall not evaluate the function when assigning just when saving so just add the function object there (without brackets).

class Discussion(models.Model):
    # attributes ...

    def __str__(self):
            return str(self.id) + ". " + self.title

    def class_name(self):
        return self.__class__.__name__

   discussion_type = models.CharField(max_length = 50, default = Discussion.class_name)

   class Meta:
       abstract = True

However, I have not tested this if this really works.

Upvotes: 0

Related Questions