override save method for FileField in models

I have a Django model where there is FileField to upload files. I want to upload the files in the templates directory under the XML folder but before saving the files there I want the file open and add the following line of code in each and every file before tags and save in the templates directory under the XML folder. So can anyone help me to read, append and override the save method in the Django model?

<?xml-stylesheet type="text/xsl" href="teibp.xsl"?>

A FileField object does not contain the file data. It contains a reference to where the data is stored on the file system.

Side note: I’d be more inclined to do this work from the view where the file is uploaded rather than in the save method of the model. This avoids doing the work every time the model is edited for fields other than the FileField.

Assuming your code has the necessary permissions to do this, you have at least two fundamental options.

  • Have the upload go to a temporary location. Then, in the process of copying the data to its final destination, perform whatever transformations needs to occur.

  • Have the upload go to it’s final destination. Then, read the entire file into memory, process it as appropriate, and write it back out.

Then, once the processing is complete, you can update the FileField with the file’s location and save the model.

class Inscription(models.Model):
    STATUS_CHOICES = (
        ('draft', 'DRAFT'),
        ('published', 'PUBLISHED'),
    )
    TEI = models.FileField(upload_to='TEI/', blank=True)

def save(self, *args, **kwargs):
    super(Inscription, self).save(*args, **kwargs)
    string = '<TEI'
    with open(self.TEI, 'r') as f:

        # setting  index to 0
        contents = f.readlines()

        index = 0

        for line in contents:
            index += 1

            # checking string is present in line or not
            if string in line:
                contents.insert(index, '<?xml-stylesheet type="text/xsl" href="teibp.xsl"?>\n')
                with open(self.TEI, "w") as f:
                    contents = "".join(contents)
                    f.write(contents)

I have done this but I am not able to pass the reference path of TEI FileField to open the file. Can you help me how can I call the path in open to read file?

Have a look at the documentation on FileField and FieldFile (link). Key point being:

When you access a FileField on a model, you are given an instance of FieldFile as a proxy for accessing the underlying file.

Relevant other documentation:

1 Like