Creating a function to Specify Directory for Uploaded Images Location

Viewed 64

I have created a function for my items model where there are images to be uploaded according to the name of the user and the title of the item.

Now I am trying to add more images to this item and there is a foreign key with the image, but now instead of creating randomly uploading the new images to another folder, I want to upload these images to the same folder that was previously determined according to the same item.

I have tried to alter the previous function but it returned with an error upload_design_to() takes 1 positional argument but 2 were given I assume because i didn't add self to the function but I don't know what to replace it with.

The functions below will be more descriptive:

Here is the models and the function where the images is uploaded to a location as per the users name and the title of the item:

class Item(models.Model):
    def upload_design_to(self, filename):
        return f'{self.designer}/{self.title}/{filename}'

    designer = models.ForeignKey(
        User, on_delete=models.CASCADE)
    title = models.CharField(max_length=100)
    image = models.ImageField(blank=False, upload_to=upload_design_to)

Now I have created a new an Image model to add more images to this item and want them to be uploaded to the very same folder

class Images(models.Model):
    def upload_design_to(filename):
        return f'{Item.designer}/{Item.title}/{filename}'
    item = models.ForeignKey(Item, on_delete=models.CASCADE)
    name = models.CharField(max_length=50, blank=True)
    image = models.ImageField(blank=True, upload_to=upload_design_to)

    def __str__(self):
        return self.name
2 Answers

A solution where you don't repeat yourself would be to call the upload_design_to of the related Item

class Images(models.Model):
    def upload_design_to(self, filename):
        return self.item.upload_design_to(filename)

    item = models.ForeignKey(Item, on_delete=models.CASCADE)
    name = models.CharField(max_length=50, blank=True)
    image = models.ImageField(blank=False, upload_to=upload_design_to)
class Images(models.Model):
    def upload_design_to(self, filename):
        return f'{self.item.designer}/{self.item.title}/{filename}'

    item = models.ForeignKey(Item, on_delete=models.CASCADE)
    name = models.CharField(max_length=50, blank=True)
    image = models.ImageField(blank=True, upload_to=upload_design_to)

    def __str__(self):
        return self.name

About the error that you raised, you can also set a max_length attribute to your filefield so that it doesn't go over the file limit. You can just set this to 10000000 or something that is long enough for your file. Reference

Related