'While saving a Django model instance, in what order are my clean() and save() overrides applied relative to methods used as ModelField attributes?

I have a model with a first_name and last_name field, and these are used to create a filename on an ImageField. The argument for upload_to on the ImageField is this method that generates the filename with this instance's information.

When this model instance is saved, would the calls to .strip() in the clean() be applied to the fields before they are used to generate the filename? Or would I need to do .strip() on the data when it's used, as well as in the clean?

models.py:

def set_path(instance, filename):
    """
    Set the path to be used for images uploaded (trainer photos).
    """
    return u'about/%(first)s_%(last)s.%(ext)s' % {
        'first': instance.first_name.strip(' \t').lower(), #.strip() required?
        'last': instance.last_name.strip(' \t').lower(), #.strip() required?
        'ext': filename.split('.')[-1]
    }

class Trainer(models.Model):
    """
    Trainers and their associated information.
    """
    first_name = models.CharField(max_length=25)
    last_name = models.CharField(max_length=25)
    image = models.ImageField(upload_to=set_path, blank=True, null=True,
        verbose_name="Trainer image")
    description = models.TextField()

    class Meta:
        unique_together = ('first_name', 'last_name',)

    def clean(self):
        super(Trainer, self).clean()
        # Are these calls to .strip() applied before the fields
        # get used as `instance` to determine a filename?
        self.first_name = self.first_name.strip(' \t')
        self.last_name = self.last_name.strip(' \t')
        self.description = self.description.strip(' \t\r\n')


Solution 1:[1]

If there is a callable for the upload_to argument, it is called during the save() method of the model base. The save() is of course called after clean(), so you do NOT need to strip() any fields if you've already done so in the clean() method.

You can see where the code is called on line 90 of the Django source code: https://code.djangoproject.com/browser/django/trunk/django/db/models/fields/files.py

generate_filename is the stored variable that points to whatever you passed into upload_to.

So, the order is form submit -> model.full_clean() -> overridden clean() -> save(), which calls upload_to()

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 chris Frisina