How to apply read/write permissions to user-uploaded files in Django
<p>I have a "document" model, an upload system using dropzone.js and the register/login. Im now lost on how to apply permissions to each individual uploaded <strong>File</strong> so only the specified users can access them.</p>

<p>Basically:
File1->accessible_by = user1,user2</p>

<p>File2->accesible_by=user3,user5...</p>

<p>And so on. </p>

<p>Thanks to anyone for advice/help on my problem.</p>

<h1>Edit with relevant code:</h1>

<h2>Create Document View:</h2>

<pre><code>class DocumentCreate(CreateView):
    model = Document
    fields = ['file', 'is_public']

    def form_valid(self, form):
        self.object = form.save()
        data = {'status': 'success'}
        response = JSONResponse(data, mimetype =
        response_mimetype(self.request))
        return response
</code></pre>

<p>I did the above to the view to handle dropzone.js file uploading.</p>

<h2>This is my "document" model</h2>

<pre><code>class Document(models.Model):

    file = models.FileField(upload_to = 'files/')
                                #validators=[validate_file_type])
    uploaded_at = models.DateTimeField(auto_now_add = True)
    extension = models.CharField(max_length = 30, blank = True)
    thumbnail = models.ImageField(blank = True, null = True)
    is_public = models.BooleanField(default = False)

    uploaded_by = models.ForeignKey(User,
                                related_name='uploadedByAsUser', null=True)

    allowed_users = models.ManyToManyField(User,
                                related_name='allowedUsersAsUser')

    def clean(self):
        self.file.seek(0)
        self.extension = self.file.name.split('/')[-1].split('.')[-1]
        if self.extension == 'xlsx' or self.extension == 'xls':
            self.thumbnail = 'xlsx.png'
        elif self.extension == 'pptx' or self.extension == 'ppt':
            self.thumbnail = 'pptx.png'
        elif self.extension == 'docx' or self.extension == 'doc':
            self.thumbnail = 'docx.png'


    def delete(self, *args, **kwargs):
        #delete file from /media/files
        self.file.delete(save = False)
        #call parent delete method.
        super().delete(*args, **kwargs)

    #Redirect to file list page.
    def get_absolute_url(self):
        return reverse('dashby-files:files')

    def __str__(self):
        return self.file.name.split('/')[-1]

    class Meta():
        ordering = ['-uploaded_at']
</code></pre>

<p>You can set content_type on a HttpResponse. So you can do permission handling in your view and serve the file directly from Django:</p>

<pre><code>return HttpResponse("Text only, please.", content_type="text/plain")
</code></pre>

<p>Note: Django isn't a web server. It is recommended to use a web server for serving static files!</p>

<p>The above method might be a good approach if you handle small amounts of data and only incidentally serve data. If you need a robust solution, you need to check permissions in Django and leave the serving of data to the web server. </p>

<ul>
<li>Lighthttpd X-Sendfile</li>
<li>Apache mod_wsgi Internal redirects</li>
<li>NGNIX X-Accel-Redirect</li>
</ul>

<p>Have a look at Django file streaming packages: <a href="https://djangopackages.org/grids/g/file-streaming/" rel="nofollow">https://djangopackages.org/grids/g/file-streaming/</a></p>

python django authentication permissions