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.