Django - upload_to dynamic path from different models

444 views Asked by At

I'm trying to use ImageField upload_to to save the image in organize manner, but I cannot figure out if this is possible or how to. I'm trying to have this folder hierarchy inside media:

Book-title
    Chapter 1
        img1
        img2
    Chapter 2
        img1

Models:

class Book(models.Model):
    title = models.CharField(max_length=250, unique=True)
    slug = models.SlugField(max_length=250, unique=True)
    author = models.ManyToManyField(Author)
    chapter = models.ManyToManyField(Chapter, related_name='books')
def image_dir_path(instance, filename):
    chapter = instance.slug
    return os.path.join(chapter, filename)


class Chapter(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    title = models.CharField(max_length=130, unique=True)
    slug = models.SlugField(max_length=150, unique=True, blank=True)
    picture = models.ImageField(upload_to=image_dir_path)
    created_at = models.DateField(auto_now_add=True)

I'd like to have something like this, so I can use the book title to build the path:

def image_dir_path(instance, filename):
    book = instance.book.slug
    chapter = instance.slug
    return os.path.join(book, chapter, filename)

This do not work, instance it's only related to the class where you call image_dir_path.

It's something similar possible?

1

There are 1 answers

0
Max On

A workaround I found is to call Book in Chapter, doing a "OneToMany" relationship. A ManyToMany was not needed.

def image_dir_path(instance, filename):
    book = instance.book.slug
    chapter = instance.slug
    return os.path.join(book, chapter, filename)


class Chapter(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    book = models.ForeignKey(
            Book,
            related_name='chapters',
            on_delete=models.CASCADE,
            default=''
    )    
    title = models.CharField(max_length=130, unique=True)
    slug = models.SlugField(max_length=150, unique=True, blank=True)
    picture = models.ImageField(upload_to=image_dir_path)
    created_at = models.DateField(auto_now_add=True)