Implement Image Upload Functionality for Django Integrated TinyMCE Editor
Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for blogging purposes, although Markdown might be better suited for blogs in some cases. However, TinyMCE does not come with built-in functionality for uploading images when integrated with Django. This guide will walk you through the steps required to implement image upload functionality manually.
Furthermore, once the image upload logic is in place, you can adapt it to implement other related functionalities within Django.
Step 1: Create Image Upload Logic
To enable image uploads, add the following logic to your views.py file:
Code Sample:
import os
from django.conf import settings
from django.http import JsonResponse
from django.utils.timezone import now
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
def handle_image_upload(request):
if request.method == 'POST':
uploaded_file = request.FILES.get('image')
if not uploaded_file:
return JsonResponse({'error': 'No file uploaded'})
file_extension = uploaded_file.name.split('.')[-1].lower()
allowed_extensions = ['jpg', 'jpeg', 'png', 'gif']
if file_extension not in allowed_extensions:
return JsonResponse({'error': 'Unsupported file type'})
current_date = now()
upload_dir = os.path.join(
settings.MEDIA_ROOT, 'content_uploads',
str(current_date.year), str(current_date.month), str(current_date.day)
)
if not os.path.exists(upload_dir):
os.makedirs(upload_dir)
file_path = os.path.join(upload_dir, uploaded_file.name)
file_url = f'{settings.MEDIA_URL}content_uploads/{current_date.year}/{current_date.month}/{current_date.day}/{uploaded_file.name}'
if os.path.exists(file_path):
return JsonResponse({'error': 'File already exists', 'url': file_url})
with open(file_path, 'wb') as destination:
for chunk in uploaded_file.chunks():
destination.write(chunk)
return JsonResponse({'message': 'Upload successful', 'file_url': file_url})
return JsonResponse({'error': 'Invalid request method'})
Step 2: Add Routes
Define routes for the image upload logic and TinyMCE in urls.py:
Code Sample:
from django.urls import path, include
from . import views
urlpatterns = [
path('image/upload/', views.handle_image_upload),
path('editor/', include('tinymce.urls')),
]
Step 3: Configure TinyMCE for Image Upload
TinyMCE requires a JavaScript configuraton file to enable image uploads. Create a file named tinymce_config.js in your project’s static/js directory:
Configuration Code:
tinymce.init({
selector: 'textarea',
images_upload_url: '/image/upload/',
height: 600,
plugins: [
'image advlist autolink lists link charmap print preview anchor',
'searchreplace visualblocks code fullscreen',
'insertdatetime media table paste help wordcount'
],
toolbar: 'undo redo | formatselect | bold italic underline | alignleft aligncenter alignright | bullist numlist | link image | code fullscreen',
language: 'en',
});
Step 4: Enable TinyMCE in Django Admin
To use TinyMCE in the Django Admin interface, you’ll need to load the relevant JavaScript files in your model admin configuration.
Example Code:
from django.contrib import admin
from .models import BlogPost
@admin.register(BlogPost)
class BlogPostAdmin(admin.ModelAdmin):
list_display = ['id', 'title', 'created_at']
class Media:
js = [
'js/tinymce/tinymce.min.js',
'js/tinymce_config.js'
]
Testing the Feature
To test the functionality, navigate to the Django Admin panel and create or edit a record containing a rich text field. You should see TinyMCE configured with the ability to upload images. Simply upload a local image and verify that its stored correctly.
Additional References
For additional customization and advanced configurations, consult the TinyMCE documentation: https://www.tiny.cloud/docs/
Conclusion
These steps provide a complete solution for adding image upload support to TinyMCE when integrated with Django. Once implemented, you can further enhance the functionality based on your specific requirements.
If you have any questions or need more assistance, feel free to reach out in the comments.