Django переименовать загруженный файл: добавить определенную строку в конце

#django #django-models #filefield

Вопрос:

  • Я ограничиваю кнопку загрузки, чтобы разрешить только файлы csv.
  • Мне нужна помощь, пожалуйста, чтобы добавить _hello в конце каждого файла, загруженного пользователем, но перед расширением. (например, user_file_name.csv автоматически становится user_file_name_hello.csv)
  • Необязательно: я бы хотел, чтобы исходный файл сначала автоматически переименовывался, а затем сохранялся в моем каталоге загрузок.

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',)
 

Спасибо!

Ответ №1:

Может быть, вам нужно что-то вроде этого:

 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)
 

Комментарии:

1. Сработало. Спасибо

2. Добро пожаловать!

Ответ №2:

Необязательно: я бы хотел, чтобы исходный файл сначала автоматически переименовывался, а затем сохранялся в моем каталоге загрузок.

Вы можете переопределить метод save(). Проверьте здесь документ Django

Возможно, вам нужен декоратор.

 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


 

И вы можете украсить свой метод сохранения модели ().

 
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.
 

кроме того,
рекомендуем переименовать ваш класс user_file

как файл пользователя

Проверьте этот PEP 8

Хорошего дня.