I have a project in Django REST framework with model like this
class Attachment
attachment_type = models.PositiveSmallIntegerField(choices=constants.AttachmentTypes.CHOICES)
creator = models.ForeignKey(User, related_name="attachments", on_delete=models.PROTECT)
file = models.FileField(upload_to='uploads/%Y/%m/%d/', max_length=511)
name = models.CharField(max_length=255)
size = models.CharField(max_length=30)
And ModelViewSet using the model with custom permissions
class AttachmentViewSet(viewsets.ModelViewSet):
queryset = models.Attachment.objects.all()
Permissions for this ViewSet are based on a user roles and work fine. Problem is with permissions to a file field. It is now accessible to whoever has the link. I need the same permissions to a file as to Attachment endpoint.
What is the proper way to do it?
I have found solution myself.
At first I made all files inaccessible via URL. Then I created another endpoint - DownloadAttachmentViewSet. This viewset only supports retrieve action. AttachmentViewSet now serves URL to DownloadAttachmentViewSet-detail instead of actual file URL. When retrieve method is run it returns FileResponse.
In this way I can use custom permissions and filtered querysets to ensure that file downloaded only by users I want.
QUick solution for someome who needs to serve only small files could be to use https://github.com/Hipo/drf-extra-fields and serialize them as Base64.