LSM
LSM

Reputation: 330

Update FileField value in instance Django Model save method

What is the best way the update the total field with value total the rows the file? Implement in model or views or other? How to make The file registration will always be through django-admin

models.py

class Registry(models.Model):

   file_upload = models.FileField(blank=True, null=False) #csv or xlsx
   total = models.CharField(max_length=100, null=True, blank=True, default=None)

   def save(self):
     with open(self.file_upload) as f:
        self.total = sum(1 for line in f)
        return self.total

Error:

 TypeError: expected str, bytes or os.PathLike object, not FieldFile

Upvotes: 2

Views: 1336

Answers (3)

Astik Anand
Astik Anand

Reputation: 13047

You can simply read the file content of the uploaded file as using .read() method.

And then do whatever you want to do with that content.

def save(self):
    self.total = sum(1 for line in self.file_upload.read())
    super(Registry, self).save(*args, **kwargs) 

No need to again open at OS level.

Upvotes: 5

Deniz Kaplan
Deniz Kaplan

Reputation: 1609

I generally choose model part if I need to use the method for most of the instances that will be created. But in this case, I probably choose Django Forms to handle this business logic. By the way, you can choose all the possibilities. At least you can achieve what you need in both cases. If the business logics changes very often, I can suggest to move these logics to views or forms. The error you have encountered is about open statement, which requires one of the types that declared in error message. To achieve that, you can change self.file_upload to self.file_upload.path which is the path that file uploaded. I strongly recommend you to use csv module or an excel file library to handle file read operations.

Upvotes: 0

binpy
binpy

Reputation: 4194

The output of self.file_upload is a FieldFile object. You should change it to self.file_upload.path where will give you the string path of file.

And to makesure your self.file_upload is not None/Null, you should validate it also.

def save(self):
    if self.file_upload:
        with open(self.file_upload.path) as f:
            ....

You can read this docs for more https://docs.djangoproject.com/en/dev/topics/files/#using-files-in-models

Upvotes: 1

Related Questions