Интеграция WYSIWYG редактора

Представленные материалы в этой статье возникли в результате целого ряда экспериментов по выбору визуального редактора(WYSIWYG) для Django.

Итак, свободно распространяемых редакторов на самом деле не так много. Я решил остановиться на TinyMCE и CKEditor(бывший FCKeditor). На самом деле насколько я понял, не стоит думать что создатели этих редакторов занимаются благотворительностью, просто они создают файл менеджеры к редактору и продают за отдельную плату. Так что авторы не бедствуют и у них есть средства и возможности на поддержку этих редакторов.

Путем долгих экспериментов я пришел к выводу что редакторы в принципе очень схожи, но у TinyMCE лучше дизайн и меньше глюков, меньше размер и лучше смотрится в панели администрирования Django.

Скриншот из панели администрирования Django(Grappelli+TinyMCE+django-filebrowser)

К сожалению когда я затевал эксперимент в TinyMCE был один баг, который в конце концов исправили, но мне пришлось перейти на CK Editor. В настоящий момент TinyMCE работает стабильно и лучше, чем CKE ditor(в CKEditor например был тоже интересный баг, когда было невозможно вставлять «ъ»).

Интеграция в модели

Создаем в папке проекта папку wysiwyg, а в ней файл __init__.py (код которого приведен ниже)

#!/usr/bin/python
# -*- encoding: utf-8 -*-

from django.db.models import Field
from django.forms import Textarea
from settings import MEDIA_URL

class WidgetWYSIWYG(Textarea):
    def __init__(self, *args, **kwargs):
        super(WidgetWYSIWYG, self).__init__(attrs={'class': 'wysiwygEditor vLargeTextField'}, *args, **kwargs)
    class Media:
        js = (
            MEDIA_URL+'common/tiny_mce/tiny_mce.js',
            MEDIA_URL+'common/filebrowser/js/TinyMCEAdmin.js',
            )
        
class WYSIWYGField(Field):
    def get_internal_type(self):
        return "TextField"

    def formfield(self, **kwargs):
        defaults = {'widget': WidgetWYSIWYG}
        defaults.update(kwargs)
        return super(WYSIWYGField, self).formfield(**defaults)

Теперь мы можем создать свою модель и вместо поля models.TextField использовать WYSIWYGField. Смотрим код models.py ниже.

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from django.db import models
import datetime
from wysiwyg import WYSIWYGField

# Create your models here.
class News(models.Model):
    """
    Новости
    """
    publish = models.BooleanField(verbose_name=u"Опубликовать", default=True)
    created = models.DateField(verbose_name=u"Дата", default=datetime.date.today)
    title = models.CharField(verbose_name=u"Заголовок", max_length=250)
    preview = models.TextField(verbose_name=u"Краткое описание")
    text = WYSIWYGField(verbose_name=u"Текст")
    
    def __unicode__(self):
        return self.title
    
    class Meta:
        ordering = ('-created',)
        verbose_name = u"Новость"
        verbose_name_plural = u"Новости"

Интеграция WYSIWYG-редактора в Flatpages(простые страницы)

Скриншот который я представил сделан именно с flatpages. В отличие от интеграции в модели, в flatpages это делается немного проще - достаточно лишь немного подправить файл admin.py(смотрим ниже), здесь мы снова будем использовать созданный пакет wysiwyg.

#!/usr/bin/python
# -*- encoding: utf-8 -*-

from django.contrib import admin
from wysiwyg import WidgetWYSIWYG

from django.db import models
from django.contrib.flatpages.models import FlatPage
from django.contrib.flatpages.admin import FlatPageAdmin as FlatPageAdminOld

class FlatPageAdmin(FlatPageAdminOld):
    formfield_overrides = {
        models.TextField: {'widget': WidgetWYSIWYG},
    }

admin.site.unregister(FlatPage)
admin.site.register(FlatPage, FlatPageAdmin)
Сбор подписей на Sborgolosov.ru