How to set imagefield in django model with dynamically set sub directories

Viewed 26

I need to upload photos to specific directories.

I have below model code.

@reversion.register()
    class Student(BaseModel):
    uuid = models.UUIDField(default=uuid.uuid4, verbose_name=_("Unique Identifier"), unique=True)
    user = models.OneToOneField(User, on_delete=models.PROTECT, db_index=True, verbose_name=_("User"))
    photo = models.ImageField(upload_to="student/", null=True, blank=True, verbose_name=_("Photo"))
    std_status = models.IntegerField(choices=STD_STATUS, default=1, verbose_name=_("Stu Sta"))
    std_no = models.AutoField(primary_key=True, verbose_name=_("Stu Num"))
    name = models.CharField(max_length=100, db_index=True, verbose_name=_("Name"))
    surname = models.CharField(max_length=100, db_index=True, verbose_name=_("Surname"))

For the photo line. It uploads photos to student/ directory. But i need to have subdirectories with User name and dates. Like "student/jenifer_argon/2019223/2022/07/01" I can set "student/" directory but username and std_no and date should be dynamically set. student/user/std_no/date user and std_no should come from above model on creation runtime. How can i do this?

It is like; everything will be on same form. But std_no and user will be set first than they will be used to set upload diretory definition and image will be uploaded to that directory.

1 Answers

A function can be passed to upload_to that is passed the instance and filename, you can construct your path using these

from datetime import date

def student_photo_path(instance, filename):
    today = date.today()
    return 'student/{0}/{1}/{2}/{3}/{4}/{5}'.format(
        instance.user.username,
        instance.std_no,
        today.year,
        today.month,
        today.day,
        filename
    )


class Student(BaseModel):
    ...
    photo = models.ImageField(upload_to=student_photo_path, null=True, blank=True, verbose_name=_("Photo"))
   ...
Related