File Uploads

Hi all! This is my first topic on this forum :slight_smile:

I am currently working on building a portal where users can upload their documents. The files are only written to an external storage and should not be accessible. So for every upload, I do the following:

  1. write file to external storage with an API Post call (Dropbox)
  2. create a record in my own database with the filename & upload date

My code is as follows:

Forms

class UploadForm(forms.Form):
    file = forms.FileField(widget=forms.ClearableFileInput(attrs={'multiple': True}))`

View (class based)

def post(self, request, *args, **kwargs):
    form_class = self.get_form_class()
    form = self.get_form(form_class)
    files = request.FILES.getlist('file_field')
    if form.is_valid():
        for f in files:
            ...  # write file to external storage with an API Post call
                 # create a record in my own database with the filename & upload date
        return self.form_valid(form)
    else:
        return self.form_invalid(form)

Currently the website is working fine, but I would like to make some improvements. Ideally I would like to use a model with a FileField, like this:

Models

class MyModel(models.Model):
    file = models.FileField(upload_to='uploads/')
    uploaded_at = models.DateTimeField(auto_now_add=True)

However, I am not sure how to set the upload_to variable. Because basically I don’t want to save the file at all. How do I implement file size limitations and extension validation? On the form level?

Or should I use Custom Storage or implement custom FILE_UPLOAD_HANDLERS ?

Your help is very much appreciated!

Hi

It sounds like you want a custom storage. django-storages provides a dropbox backend: https://django-storages.readthedocs.io/en/latest/backends/dropbox.html

However if you have code working to copy the files to dropbox and want to do the minimum hccanges, you might be able to ignore FileField entirely. Instead you could just use a CharField to store the filename.

Thanks,

Adam

Thanks for your reply Adam. I decided to use a CharField and handle the validation myself, as I need a few other customisations. Django Storages is a great tip. Cheers!