How to approach file uploads for different models in Django?

Viewed 21

Using Django 3 & Python3. What is the right way / best practice to implement this:

Say I have 2 models Project and Task like this:

class Project(models.Model):
    name = models.CharField(max_length=120)

class Task(models.Model):
    name = models.CharField(max_length=120)

And I need to be able to upload documents 'attached' to any of both models. I am doing:

class BaseDocument(models.Model):
    name = models.CharField(max_length=80)
    document_date = models.DateField()
    
    def __str__(self):
        return self.slug

    class Meta:
        abstract = True

class ProjectImage(BaseDocument):
    image = models.ImageField(upload_to='images/', blank=True)
    project = models.ForeignKey(Project, on_delete=models.CASCADE, related_name='project_images', blank=True, null=True)

class ProjectDocument(BaseDocument):
    raw_file = models.FileField(
        upload_to='raw/', blank=True, 
        storage=RawMediaCloudinaryStorage()
        )
    
    project = models.ForeignKey(Project, on_delete=models.CASCADE, related_name='project_documents', blank=True, null=True)

class TaskImage(BaseDocument):
    image = models.ImageField(upload_to='images/', blank=True)
    project = models.ForeignKey(Task, on_delete=models.CASCADE, related_name='task_images', blank=True, null=True)

class TaskDocument(BaseDocument):
    raw_file = models.FileField(
        upload_to='raw/', blank=True, 
        storage=RawMediaCloudinaryStorage()
        )
    project = models.ForeignKey(Task, on_delete=models.CASCADE, related_name='task_documents', blank=True, null=True)

And then creating urls, forms, CBVs for all the models.

This seems inefficient and not very DRY. The question basically is what is the right approach to implement a functionality like this so that the user is able to upload documents to different models.

I've been trying to implement a solution using contenttypes and GenericRelations (anticipating that I may need to attach images to other models in the future) with no success. I was not able to figure out how to implement an 'UploadView' (CreateView) that is able to create the Image/Document object and assign the content_object of the GenericRelation to project/task. I feel that this approach adds a level of complexity that I was not able to handle. If this was the right/best approach, could someone point me out to some tutorial/code sample that implements this?

I hope I am being clear enough. Thanks.

0 Answers
Related