0

I want to upload file with dynamic path i.e. YEAR/MONTH//FILES

To achieve this i am using below code

def user_directory_path(instance, filename):
    return '%Y/%B/{0}/files/{1}'.format(instance.retailer.retailer_id, filename)

class FileUpload(models.Model):
    file = models.FileField(upload_to=user_directory_path)
    car = models.ForeignKey(CarMaster, on_delete=models.CASCADE, default=None)

class CarMaster(models.Model):
    user = models.ForeignKey(User,default=None,on_delete=models.CASCADE)
    car_id = models.PositiveIntegerField(unique=True)
    car_name = models.CharField(max_length=1000)

Folder structure getting created is as below

media\%Y\%B\100000\files

Here %Y and %B should be replaced by Year and Month name which is not happening.

Is there a way we can achieve this.

Ronak
  • 187
  • 2
  • 17

2 Answers2

0

Try this one:

import os
import time
import uuid

from django.conf import settings


def prepare_directory(name: str) -> str:
   """
   Prepare a dynamic directory.
   """

   data_dirs_datetime = str(time.strftime("%y/%m"))

   file_path = os.path.join(f"{settings.MEDIA_ROOT}/{name}/{data_dirs_datetime}")

   if not os.path.exists(file_path):
      os.makedirs(file_path)

   return file_path


def user_directory_path(instance, filename: str) -> str:
   """
   Prepare path for files.
   """

   file_path = prepare_directory(name="files")

   _, ext = os.path.splitext(filename)

   file_name = str(uuid.uuid4())

   _path = f"{file_path}/{file_name}{ext}"

   return os.path.join(_path)
  • With the latest version of Django it might not work. You may face with **SuspiciousFileOperation** exception. To solve it you need to remove media path **{settings.MEDIA_ROOT}/** from **file_path**. – Maciej Januszewski May 20 '21 at 10:19
0

I was able to achieve with callable upload_to

def local_directory_path(instance, filename):
    now = instance.file_month
    return '{0}/{1}/{2}/{3}'.format(now.strftime('%Y'),now.strftime('%B'),instance.car.car_id, filename)
Ronak
  • 187
  • 2
  • 17