17

I have a Django form which saves a file to s3 through the django-storages library and works fine. How can I generate and return a pre-signed url so the user can access the file temporarily after it is uploaded ? Is this abstracted by django-storages or do I have to use the boto3 api?

I have spent hours going through the Django-storages documentation however it is not very clear how to do this ..

form.py

class DocumentForm(forms.Form):
    docfile = forms.FileField(
        label='Select a file',
        help_text='max. 42 megabytes'
    )
   name = models.CharField(max_length=20)
   uploaded_at = models.DateTimeField(auto_now_add=True)

views.py

def upload_file(request):
   if request.method == 'POST':
      form = DocumentForm(request.POST)
      if form.is_valid():
         form.save()
         url = ... # generate pre-signed url of uploaded file here
         return render(request, 'upload_response.html', url)

1

2 Answers 2

17

Turns out you do not need to use boto3 to generate a presigned url. Django-storages abstracts the entire process. You can simply access the url attribute on the FileField, like in this example:

document_form = DocumentForm.objects.get(pk=1)
url = document_form.docfile.url

--- Edit ----

For reference, here is the S3 storage class method that generates the pre-signed url for you https://github.com/jschneier/django-storages/blob/770332b598712da27ecdba75c9e202ad6a1a8722/storages/backends/s3boto3.py#L554

Sign up to request clarification or add additional context in comments.

5 Comments

Can we get a reference to source on this?
I have just edited the answer with a link to the reference
To actually return a URL with signature, make sure AWS_QUERYSTRING_AUTH = True.
Good point. I believe it is set to True by default if not explicitly set in settings.py
This is not working - the .url attribute doesn't generate the presigned URL automatically. Has this process changed? I am able to upload to S3 but I am not able to display those files since the bucket is not private.
3

Here is sample code for generating pre-signed url for object in S3

import boto3

client = boto3.client('s3')
response = client.generate_presigned_url('get_object',Params={'Bucket': bucket_name,
                                                              'Key': objectpath},
                                         HttpMethod="GET", ExpiresIn=expires_in)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.