Change File name on attach image field in frappe on upload or save of document

I have a Doctype named Student Records in my frappe app in that i have a attach image field with the field name student_image i want to concatenate the student_name field to the file name on upload or after the document is written to the system also if i could provide a custom path to save the file. Thank you in advance

1 Like

Hi @Parth_Vashista,

You can use the before_save method of your Student Records Doctype in your Frappe app. Here’s an example code snippet that should help you achieve this:

we just share the some scenario.

from frappe.utils.file_manager import save_file, get_file_name

class StudentRecords(Document):
    def before_save(self):
        if self.student_image:
            file_name = get_file_name(self.student_image)
            new_file_name = "{0}_{1}".format(self.student_name, file_name)
            file_url = save_file(file_name=new_file_name, content=self.student_image, 
                                 dt=self.doctype, dn=self.name, folder="Student Records")

            # Set the new file URL to the student_image field
            self.student_image = file_url

the before_save method checks if the student_image field is not empty. If it is not empty, it gets the original file name using the get_file_name function from frappe.utils.file_manager. It then concatenates the student_name field to the file name and saves the new file using the save_file function from frappe.utils.file_manager.

Additionally, if you want to provide a custom path to save the file, you can specify the folder parameter in the save_file function. In the example above, the files will be saved in the “Student Records” folder. You can replace this with your preferred folder name or use a variable to set it dynamically.

I hope this helps!

Thank You!

class StudentApplication(Document):
    def before_save(self):

        if self.upload_image:
            if isinstance(self.upload_image, File):
                # get the file name from the file object
                file_name = self.upload_image.name
            else:
                file_name = self.upload_image
            # check if the file name starts with the expected string
            if not file_name.startswith(("/files", "/private/files")):
                frappe.throw("File path is not valid")
            new_file_name = "{0}_{1}".format(self.student_name, os.path.basename(file_name))
            frappe.msgprint(f"{new_file_name}")
            file_path = frappe.get_site_path("public", "files")
            new_file_path = new_file_name
            frappe.msgprint(f"{new_file_path}")
            file_url = save_file(fname=new_file_path, content=self.upload_image, dt=self.doctype, dn=self.name)
            self.upload_image = file_url
            frappe.msgprint(f"{file_url}")

getting this error do you have any idea for resolution

App Versions

{
	"frappe": "14.30.0",
	"test_custom": "0.0.1"
}

Route

Form/Student Application/99

Traceback

Traceback (most recent call last):
  File "apps/frappe/frappe/app.py", line 66, in application
    response = frappe.api.handle()
  File "apps/frappe/frappe/api.py", line 54, in handle
    return frappe.handler.handle()
  File "apps/frappe/frappe/handler.py", line 45, in handle
    data = execute_cmd(cmd)
  File "apps/frappe/frappe/handler.py", line 83, in execute_cmd
    return frappe.call(method, **frappe.form_dict)
  File "apps/frappe/frappe/__init__.py", line 1608, in call
    return fn(*args, **newargs)
  File "apps/frappe/frappe/desk/form/save.py", line 26, in savedocs
    doc.save()
  File "apps/frappe/frappe/model/document.py", line 305, in save
    return self._save(*args, **kwargs)
  File "apps/frappe/frappe/model/document.py", line 339, in _save
    self.run_before_save_methods()
  File "apps/frappe/frappe/model/document.py", line 1046, in run_before_save_methods
    self.run_method("before_save")
  File "apps/frappe/frappe/model/document.py", line 914, in run_method
    out = Document.hook(fn)(self, *args, **kwargs)
  File "apps/frappe/frappe/model/document.py", line 1264, in composer
    return composed(self, method, *args, **kwargs)
  File "apps/frappe/frappe/model/document.py", line 1246, in runner
    add_to_return_value(self, fn(self, *args, **kwargs))
  File "apps/frappe/frappe/model/document.py", line 911, in fn
    return method_object(*args, **kwargs)
  File "apps/frappe/frappe/test_university/doctype/student_application/student_application.py", line 52, in before_save
    file_url = save_file(fname=new_file_path, content=self.upload_image, dt=self.doctype, dn=self.name)
  File "apps/frappe/frappe/utils/file_manager.py", line 192, in save_file
    f.insert()
  File "apps/frappe/frappe/model/document.py", line 253, in insert
    self.run_method("before_insert")
  File "apps/frappe/frappe/model/document.py", line 914, in run_method
    out = Document.hook(fn)(self, *args, **kwargs)
  File "apps/frappe/frappe/model/document.py", line 1264, in composer
    return composed(self, method, *args, **kwargs)
  File "apps/frappe/frappe/model/document.py", line 1246, in runner
    add_to_return_value(self, fn(self, *args, **kwargs))
  File "apps/frappe/frappe/model/document.py", line 911, in fn
    return method_object(*args, **kwargs)
  File "apps/frappe/frappe/core/doctype/file/file.py", line 70, in before_insert
    self.save_file(content=self.get_content())
  File "apps/frappe/frappe/core/doctype/file/file.py", line 560, in save_file
    self._content = strip_exif_data(self._content, self.content_type)
  File "apps/frappe/frappe/utils/image.py", line 33, in strip_exif_data
    original_image = Image.open(io.BytesIO(content))
TypeError: a bytes-like object is required, not 'str'

Request Data

{
	"type": "POST",
	"args": {
		"doc": "{\"name\":99,\"owner\":\"goodpathinc@gmail.com\",\"creation\":\"2023-04-27 18:56:13.410598\",\"modified\":\"2023-05-01 18:11:48.772010\",\"modified_by\":\"Administrator\",\"docstatus\":0,\"idx\":0,\"student_name\":\"Guryog\",\"student_email\":\"Goodpathinc@gmail.com\",\"student_age\":22,\"student_phone\":\"9898989698\",\"student_gender\":\"Male\",\"upload_image\":\"/files/IMG_4628.jpg\",\"auto_id\":\"Guryog/M/22\",\"is_published\":0,\"application_status\":\"Please Select\",\"doctype\":\"Student Application\",\"stundent_marks\":[],\"__last_sync_on\":\"2023-05-01T12:48:54.360Z\",\"__unsaved\":1}",
		"action": "Save"
	},
	"freeze": true,
	"headers": {},
	"error_handlers": {},
	"url": "/api/method/frappe.desk.form.save.savedocs"
}

Response Data

{
	"exception": "TypeError: a bytes-like object is required, not 'str'",
	"_server_messages": "[\"{\\\"message\\\": \\\"Guryog_IMG_4628.jpg\\\", \\\"title\\\": \\\"Message\\\"}\", \"{\\\"message\\\": \\\"Guryog_IMG_4628.jpg\\\", \\\"title\\\": \\\"Message\\\"}\"]"
}