Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django Models: Automatic value assignment to a field based on another field value

I am working through Django tutorials. In the polls application admin page, I want to create a list_filter on the basis of first character of the poll question.

To solve this, I thought of adding a field in the Question model which will have the first character of the question text as value. However, I want the value of that field to be set automatically. I tried few ways, but I could not understand few things:

The code from tutorial:

class Question(models.Model):
    def __str__(self):
        return self.question_text
    def was_published_recently(self):
        return self.pub_date >= timezone.now() -   datetime.timedelta(days=1)
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')

I tried adding another field like this:

 first_char = question_text[:1]

I received the error:

'CharField' object is not subscriptable

I guess I can't add a normal value in a model class. Why do I get this error, even though question_text is a string?

  1. I tried overriding the __init__, but even though there was no error, the database was not populated:

    def __init__(self,*args,**kwargs):
      super(Question, self).__init__(*args, **kwargs)
      self.first_char = self.question_text[:1]
    first_char = models.CharField(max_length=1)
    

How can this objective be accomplished?

Django: 1.7
Ubuntu: 14.04

like image 746
Deepak Garg Avatar asked Oct 22 '25 03:10

Deepak Garg


1 Answers

I don't think you should be adding fields to the database just to make nice filters in the admin.

Regardless, your problem is that you're not assigning first_char to the value of the object, but to a CharField, which isn't subscriptable, just as the error tells you. I would suggest going through the tutorial and learning more, but here is an answer to your question.

Override the save() method, and add the field there:

class Question(models.Model):
    ...
    first_char = models.CharField(max_length=1)

    def save(self):
        # self.first_char for referencing to the current object
        self.first_char = self.question_text[1]
        super().save(self)

Now, whenever the object is saved, first_char will be set to the first character of the question_text.

like image 124
Tom Carrick Avatar answered Oct 23 '25 19:10

Tom Carrick