Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamically change upload location based on Model name in Django

Tags:

django

I have this model:

class Photos (models.Model):
    file = models.ImageField()
    description = models.CharField(max_length=255, blank=True)
    Purpose = models.CharField(default='None', max_length=10)
    uploaded_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        verbose_name = 'photo'
        verbose_name_plural = 'photos'

    def __str__(self):
        return self.description

This model houses all of the Photos that gets uploaded to the site. I have three other models that refer to it:

class Member(Models.Model):
     ...(various fields)
     Photos = models.ManytoManyForeignKey(Photos)

class Unit(models.Model):
     ...(various fields)
     Photos = models.ManytoManyForeignKey(Photos)

class avatar(models.Model):
     ...(various fields)
     Photos = models.ForeignKey(Photos)

My question is where the files are located. I know I can add uploaded-to: parameter in the PHotos class, but is there a way that I can specialize which folder to go to based on the referring model?

such as uploaded-to: '/avatars/' when the class avatar is engaged? or to /Member-Photos/ folder for the Members class?

like image 646
arcee123 Avatar asked Jan 28 '23 17:01

arcee123


1 Answers

You could since upload_to can take a function. So basically, you could use something like,

def upload_location(instance, filename):
    return os.path.join('/media/%s/' % instance.__class__.__name__, filename) 

class Photos (models.Model):
    file = models.ImageField(upload_to=upload_location)
    ...

This will dynamically append your models class names (eg. avatar,Member,etc.)

EDIT

If ever you want to customize the names returned depending on the model instance, I'd create a dict that maps those values.

path_mapping = {'avatars':'avatars','Member':'Member-Photos'}

def upload_location(instance, filename):
    try:
        path = path_mapping[instance.__class__.__name__]
    except KeyError:
        path = 'Unknown'
    return os.path.join('/media/%s/' %path , filename) 

class Photos (models.Model):
    file = models.ImageField(upload_to=upload_location)
    ...

Note that this is not the only way of achieving this. I just find it maintainable and readable. If ever you didn't implement a custom path in your mapping dict, 'Unknown' will be used.

like image 154
scharette Avatar answered May 19 '23 06:05

scharette