I have trouble uploading images in production mode with django tinymce. It does upload images in development mode but not in production. It Would be great if someone could me help me get this going.
settings.py
import os
from pathlib import Path
import json
with open('/Users/omidsoroush/Desktop/config/config.json') as config_file:
config = json.load(config_file)
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
TEMPLATE_DIR = os.path.join(BASE_DIR,'templates')
SECRET_KEY = config['SECRET_KEY']
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = ['127.0.0.1', '59.12.303.203', 'www.example.org']
# Application definition
INSTALLED_APPS = [
'tinymce',
]
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 = 'pypro.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [TEMPLATE_DIR,],
'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 = 'pypro.wsgi.application'
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.2/howto/static-files/
STATIC_URL = "/static/"
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static'),)
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')
MEDIA_URL = "/media/"
ADMIN_MEDIA_PREFIX = STATIC_URL + 'admin/'
CRISPY_TEMPLATE_PACK = 'bootstrap4'
LOGIN_REDIRECT_URL = 'blog:blog-home'
LOGIN_URL = 'login'
TINYMCE_DEFAULT_CONFIG = {
'cleanup_on_startup': True,
'custom_undo_redo_levels': 20,
'selector': 'textarea',
'content_css': "/static/blog/tinymce/tinypage.css",
'theme': 'silver',
'file_picker_types': 'file image media',
'images_upload_url': '/upload_image/',
'height': 500,
'plugins': '''
textcolor save link image imageupload media preview codesample contextmenu
table code lists fullscreen insertdatetime nonbreaking
contextmenu directionality searchreplace wordcount visualblocks
visualchars code fullscreen autolink lists charmap print hr
anchor pagebreak spellchecker
''',
'toolbar1': '''
fullscreen preview bold italic underline | fontselect,
fontsizeselect | forecolor backcolor | alignleft alignright |
aligncenter alignjustify | indent outdent | bullist numlist table |
| link image media | codesample |
''',
'toolbar2': '''
visualblocks visualchars |
charmap hr pagebreak nonbreaking anchor | code |removeformat
''',
'contextmenu': 'formats | link image',
'menubar': True,
'statusbar': True,
}
# Default primary key field type
# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
views.py
import os
from django.conf import settings
from django.http import JsonResponse
from django.utils import timezone
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
def upload_image(request):
if request.method == "POST":
file_obj = request.FILES['file']
file_name_suffix = file_obj.name.split(".")[-1]
if file_name_suffix not in ["jpg", "png", "gif", "jpeg", ]:
return JsonResponse({"message": "Wrong file format"})
upload_time = timezone.now()
path = os.path.join(
settings.MEDIA_ROOT,
'tinymce',
str(upload_time.year),
str(upload_time.month),
str(upload_time.day)
)
# If there is no such path, create
if not os.path.exists(path):
os.makedirs(path)
file_path = os.path.join(path, file_obj.name)
file_url = f'{settings.MEDIA_URL}tinymce/{upload_time.year}/{upload_time.month}/{upload_time.day}/{file_obj.name}'
if os.path.exists(file_path):
return JsonResponse({
"message": "file already exist",
'location': file_url
})
with open(file_path, 'wb+') as f:
for chunk in file_obj.chunks():
f.write(chunk)
return JsonResponse({
'message': 'Image uploaded successfully',
'location': file_url
})
return JsonResponse({'detail': "Wrong request"})
urls.py
from django.contrib import admin
from django.urls import path, include
from django.contrib.auth import views as auth_views
from . import views as img_views
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('blog.urls' , namespace='blog')),
path('tinymce/', include('tinymce.urls')),
path('upload_image/', img_views.upload_image),
]
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root = settings.MEDIA_ROOT)
apache2.conf
Alias /static /home/omid/pypro/staticfiles
<Directory /home/omid/pypro/staticfiles>
Require all granted
</Directory>
Alias /media /home/omid/pypro/media/
<Directory /home/omid/pypro/media>
Require all granted
</Directory>
<Directory /home/omid/pypro/pypro>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
When I try to upload images in production mode, the images which are already in the media directory can be upload. But new images (not in media directory are not upload).
I get HTTP Error: 500
I found it out. I just needed to give read and write permission to the media directory