S3 bucket does not collect created pdfs in media folder django/aws
I just deployed my django application to a beanstalk server linked to an s3 bucket in the aws console.
In my application pdfs from each post are created and forwarded to the media folder in the subfolder "postings". However, in the bucket no such folder is created and the pdfs also don't show up anywhere else. only the uploaded images of the post is there. How do I get the pdfs there? also, I get an ValueError now for the Image in the PDF (which is the uploaded image, and which was working just fine before adding the bucket). How do I get it to work again? I think both problems are due to some connection missing... This is my first project deploying to aws. Please help me out with a little explanation.
Here is the code of the created upload and pdf: views.py
def post_create(request):
if request.method == 'POST':
form = PostCreateForm(request.POST, request.FILES)
if form.is_valid():
form.cleaned_data['num_post'] = Post.objects.count() + 1
Post.objects.create(**form.cleaned_data)
else:
form = PostCreateForm()
return render(request, 'index.html', {'form': form})
def upload(request):
if request.method == 'POST':
image = request.FILES.get('image_upload')
caption = request.POST['caption']
num_post = Post.objects.count() + 1
new_post = Post.objects.create(image=image, caption=caption, num_post=num_post)
new_post.save()
# create pdf
buffer = io.BytesIO()
x_start = 100
y_start = 100
folder_path = f"media/postings/post{num_post}.pdf"
folder_name = os.path.join(BASE_DIR, folder_path)
p = canvas.Canvas(folder_name, pagesize=A4, )
if image is not None:
register_heif_opener()
pil_image = io.BytesIO()
PIL.Image.open(image.file).save(pil_image, 'PNG')
p.drawImage(ImageReader(PIL.Image.open(pil_image)), x_start, y_start, width=420, preserveAspectRatio=True,
mask='auto')
p.drawString(150, 650, new_post.caption)
p.drawString(100, 650, "caption:")
p.drawString(100, 170, str(new_post.created_at))
p.drawString(200, 700, str(num_post))
p.drawString(100, 700, "post no.:")
p.drawString(250, 700, "//")
p.drawString(100, 690, "===========================================================")
p.drawString(300, 700, str(new_post.id))
p.save()
buffer.seek(0)
return redirect('/')
else:
return redirect('/')
the Post Model
def post_images(instance, filename):
ext = filename.split('.')[-1]
filename = 'postimg{}.{}'.format(instance.num_post, ext)
return os.path.join('uploads', filename)
class Post(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4)
num_post = models.IntegerField(default=0)
image = models.ImageField(upload_to=post_images)
caption = models.TextField(max_length=300)
created_at = models.DateTimeField(auto_now_add=True)
number_of_likes = models.IntegerField(default=0)
number_of_dislikes = models.IntegerField(default=0)
likes_string = models.TextField(max_length=800, default="")
dislikes_string = models.TextField(max_length=800, default="")
interaction_count = models.IntegerField(default=0)
@property
def filename(self):
return os.path.basename(self.image.name).split('.')[0]
def __str__(self):
return self.caption
the media settings
from django.contrib import staticfiles
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/4.1/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = "..."
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = getenv("IS_DEVELOPMENT", True)
ALLOWED_HOSTS = [
getenv("APP_HOST", "localhost"),
'127.0.0.1'
]
# Application definition
INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
'core.apps.CoreConfig',
'storages'
]
MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
]
ROOT_URLCONF = "social_book.urls"
TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [os.path.join(BASE_DIR, 'templates')]
,
"APP_DIRS": True,
"OPTIONS": {
"context_processors": [
"django.template.context_processors.debug",
"django.template.context_processors.request",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
],
},
},
]
WSGI_APPLICATION = "social_book.wsgi.application"
# Database
# https://docs.djangoproject.com/en/4.1/ref/settings/#databases
DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql",
"NAME": "postgres",
"USER": "feedingcycle",
"PASSWORD": "...",
"HOST": "django-social-media.cuo1odqldl3u.us-east-1.rds.amazonaws.com",
"PORT": "5432"
}
}
# Password validation
# https://docs.djangoproject.com/en/4.1/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",
},
{"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator", },
{"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator", },
{"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator", },
]
# Internationalization
# https://docs.djangoproject.com/en/4.1/topics/i18n/
LANGUAGE_CODE = "en-us"
TIME_ZONE = "UTC"
USE_I18N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.1/howto/static-files/
STATIC_URL = "static/"
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STATICFILES_DIRS = (os.path.join(BASE_DIR, 'static'),)
# Default primary key field type
# https://docs.djangoproject.com/en/4.1/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
AWS_STORAGE_BUCKET_NAME = "django-feeding-cycle"
AWS_S3_REGION_NAME = "us-east-1"
AWS_ACCESS_KEY_ID = "..."
AWS_SECRET_ACCESS_KEY = "..."
AWS_S3_CUSTOM_DOMAIN = f"{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com"
STATICFILES_STORAGE = "storages.backends.s3boto3.S3Boto3Storage"
MEDIAFILES_FOLDER = "media"
DEFAULT_FILE_STORAGE = "custom_storages.MediaFileStorage"
the storage
from django.conf import settings
from storages.backends.s3boto3 import S3Boto3Storage
class MediaFileStorage(S3Boto3Storage):
location = settings.MEDIAFILES_FOLDER
and the config
option_settings:
aws:elasticbeanstalk:environment:proxy:staticfiles:
/static: staticfiles
/media: media
So when I create an media folder like this, i get the error and no pdf is created. if i just use the default in the bucket I don't get the error but still no pdf is created... in the project preview server everything was working just fine. also without the bucket. But i need the bucket, so that I can sinc it with a local folder, to get the posted files directly...