title: How to upload an image in django using S3Boto3Storage where the path is set dynamically from the view in django
body: <p>I'm wanting to save images to an S3 bucket using the session_key as the directory inside the bucket, in django.</p>
  <p>I have created a test page that uploads an image to a set location in the bucket but don't know how to use the session_key to set the upload location dynamically.</p>
  <p>I've looked at the docs for <code>django-storages</code> and I can see a way to do this if it wasn't for the fact that I am using a <code>ModelForm</code>.</p>
  <p>Here is the code I have (I have omitted my settings.py with the bucket name and credentials):</p>
  <p><code>storage_backends.py</code></p>
  <pre class="lang-py prettyprint-override"><code>from storages.backends.s3boto3 import S3Boto3Storage
  
  class TestS3MediaStorage(S3Boto3Storage):
      location = 'dev/'
      default_acl = 'public-read'
      file_overwrite = False
  
  </code></pre>
  <p><code>models.py</code></p>
  <pre class="lang-py prettyprint-override"><code>from .storage_backends import TestS3MediaStorage
  
  class TestS3Upload(models.Model):
      uploaded_at = models.DateTimeField(auto_now_add=True)
      file = models.FileField(storage=TestS3MediaStorage())
  
  </code></pre>
  <p><code>forms.py</code></p>
  <pre class="lang-py prettyprint-override"><code>from .models import TestS3Upload
  
  class TestS3UploadForm(forms.ModelForm):
  
      class Meta:
          model = TestS3Upload
          fields = ['file']
  </code></pre>
  <p><code>views.py</code></p>
  <pre class="lang-py prettyprint-override"><code>from django.shortcuts import render
  from django.http import HttpResponse
  
  from .forms import TestS3UploadForm
  
  def test_s3_upload(request):
  
      # create session if it doesn't already exist
      if not request.session.session_key:
          request.session.create()
  
      # not quite sure how to use this to set upload destination
      session_key = request.session.session_key
  
      if request.method == 'POST':
  
          form = TestS3UploadForm(request.POST, request.FILES)
  
          if form.is_valid():
              form.save()
              return HttpResponse(&quot;upload successful!&quot;)
      else:
          form = TestS3UploadForm()
  
      return render(
          request,
          'uploader/test_s3_upload.html',
          {
              'form': form
          }
      )
  
  </code></pre>
  <p><code>test_s3_upload.html</code></p>
  <pre class="lang-html prettyprint-override"><code>&lt;h1&gt;Test S3 file upload&lt;/h1&gt;
  &lt;form method=&quot;POST&quot; enctype=&quot;multipart/form-data&quot;&gt;
      {% csrf_token %}
      {{ form.as_p }}
      &lt;button type=&quot;submit&quot;&gt;Upload photo to S3 Bucket&lt;/button&gt;
  &lt;/form&gt;
  
  </code></pre>
  <p><a href="https://i.stack.imgur.com/1O0pT.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/1O0pT.png" alt="screenshot of rendered template page showing upload of image" /></a></p>
  <p>When I run my code and upload an image, for example <code>car.jpg</code>, it uploads successfully but the path inside the S3 bucket is</p>
  <p><code>&lt;bucket-name&gt;/dev/car.jpg</code></p>
  <p>and i want</p>
  <p><code>&lt;bucket-name&gt;/dev/&lt;session-key&gt;/car.jpg</code></p>
  <p>The packages needed are <code>boto3</code> and <code>django-storages</code> in case anyone who wants to help answer needs to know.</p>