Home > front end >  Django rename uploaded file: append specific string at the end
Django rename uploaded file: append specific string at the end

Time:11-11

  • I'm restricting the upload button to allow only csv files.
  • I need help please to append _hello at the end of each file uploaded by the user, but before the extension. (e.g. user_file_name.csv becomes automatically user_file_name_hello.csv)
  • Optional: I'd like the original file to be first renamed automatically, then saved to my uploads directory.

models.py

from django.db import models

# validation method to check if file is csv
from django.core.exceptions import ValidationError
def validate_file_extension(value):
    if not value.name.endswith('.csv'):
        raise ValidationError(u'Only CSV files allowed.')

# Create your models here.

class user_file(models.Model):
    user_file_csv = models.FileField(upload_to='documents/user_files/', validators=[validate_file_extension])

forms.py

from django import forms
from .models import user_file
from django.forms import FileInput

class user_file_form(forms.ModelForm):
    class Meta:
        model = user_file
        widgets = {'user_file_csv': FileInput(attrs={'accept': 'text/csv'})}
        fields = ('user_file_csv',)

Thank you!

CodePudding user response:

Maybe you need something like this:

class FileUploadUtil:

    @staticmethod
    def my_files_path(instance, filename):
        name, file_extention = os.path.splitext(filename)
        name = 'prefix-{}-{}-sufix.{}'.format(name, instance.id, file_extention)
        return "my_files/{}".format(name)


class MyModel(models.Model):
    # Other fields
    # ...
    my_file = models.FileField(max_length=300, upload_to=FileUploadUtil.my_files_path)

CodePudding user response:

Optional: I'd like the original file to be first renamed automatically, then saved to my uploads directory.

You can override save() method. Check here Django document

Maybe You need decorator.

from pathlib import Path


def rename_helper(path: str, append_text: str):
    stem, suffix = Path(path).stem, Path(path).suffix
    return f"{stem}{append_text}{suffix}"


def rename_previous_image(func):
    """ return wrapper object """
       
        
    def wrapper(*args, **kwargs):
        
        self = args[0]
        model = type(self)
        previous_obj = model.objects.filter(pk=self.pk)
        if previous_obj.exists():
            old_name_with_path = Path(str(previous_obj[0].user_file_csv))
            Path.rename(old_name_with_path , rename_helper(path=old_name_with_path , append_text="_hello"))
        return func(*args, **kwargs)

    return wrapper


And, You can decorate your model save() method.


class MyModel(models.Model):
    # Other fields
    # ...
    my_file = models.FileField(max_length=300, upload_to=FileUploadUtil.my_files_path)

    @rename_previous_image
    def save(self, **kwargs):
        super(user_file, self).save(**kwargs)  # You must add This row.

besides,
recommend rename your user_file class

like UserFile

Check This PEP 8

Have a good day.

  • Related