Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
*.sqlite3
*.pyc
local_settings.py
36 changes: 36 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Storing static and media files on Spaces with Django

This example application uses Digital Ocean's [Spaces](https://www.digitalocean.com/products/spaces "You create them in your Digital Ocean account") to store `static` and `media` files for a Django project.

There are a few key steps to make this work:

1. Your app is deployed to Digital Ocean. A common way to do that is with Apps.
2. You have created a space on Spaces
3. You've got the access key, the secret, the bucket name, and the region from the space
4. Boto and a lightweight custom storage make it all work in the background.


## Getting started with this repo

Create a virtual environment, install dependencies, and migrate. Assumes you've got a `DATABASE_URL` in your environment variables.


$ virtualenv -p python3.10 env
$ source env/bin/activate
$ pip install -r requirements
$ python manage.py migrate

## Next, step up your Spaces on Digital Ocean

1. Create a new space (also called a bucket)
2. Choose a region close to where most of your users are, I chose NYC 3
3. Give it a name that makes sense for what's in your space
4. When it's created, go back to Spaces and click `Manage Keys`
5. Under "Spaces access keys" click the button to `Generate New Key`
6. Give it a name. When it's generated, **BE SURE** to copy the secret and the access key.
7. You should now have the information to create 4 environment variables:
1. `SPACES_ACCESS_KEY`
2. `SPACES_SECRET_KEY` this is only shown **once** when you create your keys
3. `SPACES_BUCKET` this is the friendly name you gave your bucket in step #3 above
4. `SPACES_REGION_NAME` you should see this in your spaces url, something like `nyc3` as part of `bucket-name.nyc3.digitaloceanspaces.com`
8. Once those environment variables are in, your custom backend is effectively configured.
9 changes: 0 additions & 9 deletions custom_storages.py

This file was deleted.

Binary file removed db.sqlite3
Binary file not shown.
23 changes: 23 additions & 0 deletions jobs/migrations/0002_auto_20220930_1336.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Generated by Django 3.2.5 on 2022-09-30 13:36

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('jobs', '0001_initial'),
]

operations = [
migrations.AlterField(
model_name='job',
name='image',
field=models.ImageField(upload_to='static/'),
),
migrations.AlterField(
model_name='job',
name='summary',
field=models.CharField(max_length=500),
),
]
4 changes: 3 additions & 1 deletion jobs/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
# Create your models here.
class Job(models.Model):
# IMAGES
image = models.ImageField(upload_to='static/')
image = models.ImageField(upload_to='media/job_images/')
# SUMMARY

summary = models.CharField(max_length=500)

# Project Type
#project = models.CharField(max_length=200)

Expand Down
24 changes: 15 additions & 9 deletions portfolio/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = False

ALLOWED_HOSTS = os.getenv("DJANGO_ALLOWED_HOSTS", "127.0.0.1,localhost,159.203.76.97").split(",")
ALLOWED_HOSTS = os.getenv("DJANGO_ALLOWED_HOSTS", "127.0.0.1,localhost").split(",")


# Application definition
Expand Down Expand Up @@ -79,8 +79,8 @@
# https://docs.djangoproject.com/en/3.2/ref/settings/#databases

DATABASES = {
"default": dj_database_url.parse(os.environ.get("DATABASE_URL")),
}
"default": dj_database_url.config(default=os.environ.get("DATABASE_URL", "sqlite:///db.sqlite3")),
}


# Password validation
Expand Down Expand Up @@ -135,20 +135,21 @@
##### SPACES STORAGE CONFIGURATIONS
AWS_ACCESS_KEY_ID = os.environ.get("SPACES_ACCESS_KEY")
AWS_SECRET_ACCESS_KEY = os.environ.get("SPACES_SECRET_KEY")
AWS_STORAGE_BUCKET_NAME = os.environ.get("BUCKET_NAME")
AWS_S3_ENDPOINT_URL = 'https://nyc3.digitaloceanspaces.com'
AWS_STORAGE_BUCKET_NAME = os.environ.get("SPACES_BUCKET_NAME")
AWS_REGION_NAME = os.environ.get("SPACES_REGION") # something like "nyc3"
AWS_S3_ENDPOINT_URL = 'https://%s.digitaloceanspaces.com' % AWS_REGION_NAME
AWS_S3_OBJECT_PARAMETERS = {
'CacheControl': 'max-age=86400',
}
########### LINKEDIN TUTORIAL SITE CODE ################
STATICFILES_LOCATION = 'static'
STATICFILES_STORAGE = 'custom_storages.StaticStorage'
STATIC_URL = 'https://%s/%s/' % (AWS_S3_ENDPOINT_URL, STATICFILES_LOCATION)
STATICFILES_STORAGE = 'portfolio.custom_storages.StaticStorage'
STATIC_URL = '%s/%s/' % (AWS_S3_ENDPOINT_URL, STATICFILES_LOCATION)


MEDIAFILES_LOCATION = 'media'
DEFAULT_FILE_STORAGE = 'custom_storages.MediaStorage'
MEDIA_URL = 'https://%s/%s/' % (AWS_S3_ENDPOINT_URL, 'media')
DEFAULT_FILE_STORAGE = 'portfolio.custom_storages.MediaStorage'
MEDIA_URL = '%s/%s/' % (AWS_S3_ENDPOINT_URL, 'media')
########################################################

#STATICFILES_DIRS = [
Expand All @@ -169,3 +170,8 @@
# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field

DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

try:
from .local_settings import *
except ImportError:
pass
9 changes: 1 addition & 8 deletions portfolio/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,10 @@
from django.contrib import admin
from django.urls import path
import jobs.views
import os
from django.conf import settings
from django.conf.urls.static import static
from storages.backends.s3boto3 import S3Boto3Storage


urlpatterns = [
path('admin/', admin.site.urls),
path('', jobs.views.home, name='home'),
path('jobs/<int:job_id>', jobs.views.detail, name='detail'),
]
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATICFILES_LOCATION)
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIAFILES_LOCATION)
#urlpatterns += static(settings.STATICFILES_DIRS, document_root=settings.STATICFILES_STORAGE)
]
13 changes: 6 additions & 7 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
dj-database-url==0.5.0
Django==3.2.5
gunicorn==20.1.0
Pillow==8.3.0
psycopg2==2.8.4
psycopg2-binary==2.9.1
whitenoise==3.3.1
asgiref==3.4.1
boto3==1.17.111
botocore==1.20.111
dj-database-url==0.5.0
Django==3.2.5
django-environ==0.9.0
django-storages==1.11.1
gunicorn==20.1.0
jmespath==0.10.0
Pillow==9.2.0
psycopg2-binary==2.9.1
python-dateutil==2.8.2
pytz==2021.1
s3transfer==0.4.2
six==1.16.0
sqlparse==0.4.1
urllib3==1.26.6
whitenoise==3.3.1
1 change: 1 addition & 0 deletions runtime.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
python-3.10.4