The default Django model field is based on a different field in the same model.

I have a model in which I would like to indicate the name of the topic and its initials. (The data is somewhat anonymous and is tracked by initials.)

Right now i wrote

class Subject(models.Model): name = models.CharField("Name", max_length=30) def subject_initials(self): return ''.join(map(lambda x: '' if len(x)==0 else x[0], self.name.split(' '))) # Next line is what I want to do (or something equivalent), but doesn't work with # NameError: name 'self' is not defined subject_init = models.CharField("Subject Initials", max_length=5, default=self.subject_initials) 

As indicated on the last line, I would prefer that the initials are actually stored in the database as a field (regardless of the name), but it is initialized with a default value based on the name field. However, I am having problems because django models do not seem to have a self.

If I changed the line to subject_init = models.CharField("Subject initials", max_length=2, default=subject_initials) , I can do syncdb, but I can not create new themes.

Is this possible in django if the called function gives a default field based on the value of another field?

(Curiously, the reason I want to separate my store’s initials separately is, in rare cases, when strange surnames may differ from the ones I’m tracking. For example, someone else decided that topic 1 is named “John O'Mallory” The initials are "JM", not "JO", and you want to fix it as an administrator.)

+51
python django django-models
Dec 07 '10 at 19:43
source share
2 answers

Models certainly have an "I"! It’s just that you are trying to define the attribute of the model class as dependent on the model instance; this is not possible because the instance does not exist (and cannot) exist before you define the class and its attributes.

To get the desired effect, override the save () method of the model class. Make the necessary changes to the required instance, then call the superclass method to actually save. Here is a brief example.

 def save(self, *args, **kwargs): if not self.subject_init: self.subject_init = self.subject_initials() super(Subject, self).save(*args, **kwargs) 

This is described in Overriding Model Methods in the documentation.

+49
Dec 07 '10 at 20:29
source share

I don't know if there is a better way to do this, but you can use a signal handler for the pre_save signal :

 from django.db.models.signals import pre_save def default_subject(sender, instance, using): if not instance.subject_init: instance.subject_init = instance.subject_initials() pre_save.connect(default_subject, sender=Subject) 
+11
Dec 07 '10 at 19:50
source share



All Articles