Uploading Files with HTMX & S3
Learn about Uploading Files with HTMX & S3
Why Use S3 for File Storage?
Storing uploaded files on the local filesystem works for development, but in production you need a cloud storage solution. Amazon S3 (Simple Storage Service) is the most widely used object storage service. It provides virtually unlimited storage, built-in redundancy, and global content delivery capabilities.
Setting Up an S3 Bucket
Log into the AWS Management Console and navigate to S3. Create a new bucket with a unique name like "django-htmx-contacts-media". Configure the bucket to allow public read access for the uploaded images, since they will be displayed on the website. Set up a CORS policy that allows requests from your domain.
Installing django-storages and boto3
Install the packages needed to connect Django to S3:
pip install django-storages boto3
Add "storages" to your INSTALLED_APPS in settings.py.
Configuring Django Settings
In settings.py, add the AWS configuration variables: AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_STORAGE_BUCKET_NAME, and AWS_S3_REGION_NAME. Set the DEFAULT_FILE_STORAGE to "storages.backends.s3boto3.S3Boto3Storage" so Django automatically uploads media files to S3 instead of the local filesystem.
HTMX File Upload Configuration
Ensure your form element has the hx-encoding="multipart/form-data" attribute. HTMX needs this to correctly encode file data in the AJAX request. The Django view receives the file in request.FILES just like a normal form submission. When form.save() is called, django-storages automatically handles the upload to S3.
Displaying Uploaded Images
In your contact display templates, use the contact.photo.url attribute to get the full S3 URL of the uploaded image. Display it in an img tag. Add appropriate sizing and a rounded class for profile photos. Handle the case where no photo has been uploaded by showing a default placeholder avatar.