Reputation: 1806
I use django-wysiwyg-redactor with django 1.8
and python 2.7.9
.
Here is my code :
settings.py:
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'redactor',
)
import os
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
MEDIA_ROOT = os.path.join(BASE_DIR, 'media'),
MEDIA_URL = '/media/'
# WYSIWYG redactor configuration
REDACTOR_OPTIONS = {'lang': 'fr', 'plugins': ['table', 'fontcolor', 'fontsize', 'filemanager', 'imagemanager']}
REDACTOR_UPLOAD = MEDIA_ROOT
REDACTOR_UPLOAD_HANDLER = 'my_app.apps.core.storage.UploadDateDirectoryUploader'
REDACTOR_FILE_STORAGE = 'my_app.apps.core.storage.redactor_storage'
All the plugins .js are in the static files.
my_app.apps.core.storage.py:
from django.core.files.storage import FileSystemStorage
from django.conf import settings
import redactor.handlers
import datetime
redactor_storage = FileSystemStorage(location=settings.MEDI_ROOT, base_url=settings.MEDIA_URL)
class UploadDateDirectoryUploader(redactor.handlers.SimpleUploader):
"""
Handler that saves files in a directory based on the current date
/2014/3/28/filename.etc
"""
def get_upload_path(self):
today = datetime.datetime.today()
path = '{0}/{1}/{2}'.format(today.year, today.month, today.day)
return path
forms.py
from django import forms
from django.conf import settings
from django.utils.translation import ugettext as _
from redactor.widgets import RedactorEditor
import datetime
LANGUAGES = settings.LANGUAGES
class NewsForm(forms.Form):
title = forms.CharField(label=_('The news title'), max_length=100)
message = forms.CharField(label=_('Enter your message'), widget=RedactorEditor())
start_date = forms.DateTimeField(label=_('The news will be published the'), initial=datetime.datetime.now())
end_date = forms.DateTimeField(label=_('The news will be removed the'), required=False)
active = forms.BooleanField(initial=False, widget=forms.HiddenInput())
language = forms.ChoiceField(choices=LANGUAGES, initial='fr', widget=forms.HiddenInput())
In my template, I have no redactor related code, I generate the form with django-crispy-forms. Visually, the redactor field is rendered correctly, in the toolbar I have all the plugin button available. When Redactor is initialized, this redactor view is called :
.virtualenvs/my_app/lib/python2.7/site-packages/redactor/views.py :
import json
from django.conf import settings
from django.utils.translation import ugettext as _
from django.http import HttpResponse
from django.views.generic import FormView
from django.contrib.admin.views.decorators import staff_member_required
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt
from django.utils.encoding import force_str
from redactor.forms import ImageForm
from redactor.utils import import_class, is_module_image_installed
class RedactorUploadView(FormView):
form_class = ImageForm
http_method_names = ('post',)
upload_to = getattr(settings, 'REDACTOR_UPLOAD', 'redactor/')
upload_handler = getattr(settings, 'REDACTOR_UPLOAD_HANDLER',
'redactor.handlers.SimpleUploader')
print "RedactorUploadView : upload_to {0} | upload_handler {1}".format(upload_to, upload_handler)
@method_decorator(csrf_exempt)
@method_decorator(staff_member_required)
def dispatch(self, request, *args, **kwargs):
print "RedactorUploadView dispatch : kwargs : {0}".format(self.kwargs)
if not is_module_image_installed():
data = {
'error': _("ImproperlyConfigured: Neither Pillow nor PIL could be imported: No module named 'Image'"),
}
return HttpResponse(json.dumps(data),
content_type='application/json')
return super(RedactorUploadView, self).dispatch(request, *args,
**kwargs)
def form_invalid(self, form):
print "RedactorUploadView form_invalid : kwargs : {0}".format(self.kwargs)
# TODO: Needs better error messages
try:
error = form.errors.values()[-1][-1]
except:
error = _('Invalid file.')
data = {
'error': error,
}
return HttpResponse(json.dumps(data), content_type='application/json')
def form_valid(self, form):
print "RedactorUploadView form_valid : kwargs : {0}".format(self.kwargs)
file_ = form.cleaned_data['file']
handler_class = import_class(self.upload_handler)
uploader = handler_class(file_, upload_to=self.kwargs.get('upload_to', None))
uploader.save_file()
file_name = force_str(uploader.get_filename())
file_url = force_str(uploader.get_url())
data = {
'filelink': file_url,
'filename': file_name,
}
return HttpResponse(json.dumps(data), content_type='application/json')
upload_to
and upload_handler
are initialized correctly with upload_to
being the path to my media folder and upload_handler
my storage.py UploadDateDirectoryUploader
class.
But then when I add an image in the wysiwyg, the dispatch class method of redactor view.py is called with upload_to = ''
!
I've searched for hours for a solution, but I can't understand why suddenly the initial value of upload_to is not my /media/
folder anymore ?
In my template, I have an alert showing up with True
inside it (great error message) I think it comes from the default image upload callback function :
redactor/jquery.redactor.init.js :
if(typeof django !== "undefined") {
jQuery = django.jQuery.noConflict(true);
}
var image_upload_error_callback = function (json) {
// TODO: Needs better error messages
alert(json.error);
}
redactor_default_options = {
imageUploadErrorCallback: image_upload_error_callback
};
Upvotes: 1
Views: 654