4

I'm new to Django and CKEditor and had been struggling with integration of Django-CKEditor in forms from past 1 week. It works perfectly fine in Django Admin forms but does not work in normal forms.

This is my forms.py

class ArticleForm(forms.ModelForm):
    content = forms.CharField(widget = CKEditorWidget())    

    class Meta:
        model = Article
        fields = ['title','content','meta_description','meta_tags']

models.py

class Article(models.Model):
    title = models.CharField(max_length=500)
    url = models.CharField(max_length=500)
    date = models.DateTimeField(auto_now_add=True, blank=True)
    author = models.CharField(max_length=100)
    content = models.TextField()
    meta_description = models.TextField()
    meta_tags = models.TextField()
    is_published = models.BooleanField(default=False)

views

def new_post(request):
    if request.method == 'POST':
        form = ArticleForm(request.POST)
        if form.is_valid():
            article = form.save(commit=False)
            article.url =  form.data['title']
            article.save()
            return HttpResponse('/thanks/')
    else:
        form = ArticleForm()
    return render(request, 'blog/new-post.html', {'form': form})

TO verify whether it works in admin, I had tested with Admin by adding it in admin form.

admin.py

class ArticleAdminForm(forms.ModelForm):
    content = forms.CharField(widget=CKEditorWidget())

    class Meta:
        model = Article

class ArticleAdmin(admin.ModelAdmin):
    form = ArticleAdminForm


admin.site.register(Article, ArticleAdmin)

One more thing I'm using bootstrap3. and my template looks like

<form class="form-horizontal" action="/blog/new-post/" method="post" >{% csrf_token %}
            <fieldset>
              <legend>New Blog Post</legend>
                {{ form.non_field_errors }}
                <div class="fieldWrapper form-group">
                    {{ form.title.errors }}
                    <label class="col-lg-2 control-label" for="id_title">Title</label>
                    <div class="controls col-lg-10 ">
                      <input type="text" class="col-lg-10 form-control" name="title" id="id_title}}" placeholder="Title">
                    </div>
                </div>
                <div class="fieldWrapper form-group">
                    {{ form.content.errors }}
                    <label class="col-lg-2 control-label" for="id_content">Content</label>
                    <div class="controls col-lg-10 ">
                      <textarea class="col-lg-10 form-control" rows="17"name="content" id="id_content}}" placeholder="Content"></textarea>
                    </div>
                </div>
                <div class="fieldWrapper form-group">
                    {{ form.meta_description.errors }}
                    <label class="col-lg-2 control-label" for="id_meta_description">Description</label>
                    <div class="controls col-lg-10 ">
                      <textarea class="col-lg-10 form-control" rows="5"name="meta_description" id="id_meta_description}}" placeholder="Short description about this article."></textarea>
                    </div>
                </div>
                <div class="fieldWrapper form-group">
                    {{ form.meta_tags.errors }}
                    <label class="col-lg-2 control-label" for="id_meta_tags">Tags</label>
                    <div class="controls col-lg-10 ">
                      <input type="text" class="col-lg-10 form-control" name="meta_tags" id="id_meta_tags}}" placeholder="Comma separated tags eg. trekking, hiking ">
                    </div>
                </div>

              <input type="submit" value="Publish"  class="btn btn-default btn-large pull-right">
            </fieldset>
          </form>

Any help would be great. Thanks in advance

vaibhav1312
  • 863
  • 4
  • 13
  • 31

5 Answers5

2

When rendering ckeditor outside the admin panel you have to include/import the form media for it to work. Rendering outside of django admin.

Let's say your forms.py is like this:

from ckeditor.widgets import CKEditorWidget

class ArticleForm(forms.Form):
    content = forms.CharField(widget = CKEditorWidget())

Your template:

<form>
{{ article_form }}
</form>

And then load the form media:

{% load static %}
<script type="text/javascript" src="{% static 'ckeditor/ckeditor-init.js' %}"></script>
<script type="text/javascript" src="{% static 'ckeditor/ckeditor/ckeditor.js' %}"></script>
1

I think you missed the from ckeditor.fields import RichTextField line in models.py

Change content = models.TextField()

Into content = RichTextField(blank=True, null=True)

Employee
  • 3,109
  • 5
  • 31
  • 50
0

I went through the same problem. I rather used django-tinymce for my normal forms and ckeditor for admin page.

This is my forms.py file:

from tinymce.widgets import TinyMCE
from django import forms
from .models import Article
class ArticleForm(forms.ModelForm):
    content = forms.CharField(widget=TinyMCE(attrs={'cols': 80, 'rows': 30}))
    class Meta:
        model = Article
        fields = ('content',)

Hope this helps.

Indox
  • 11
  • 2
0

Most probably you have missed {{form.media}} modify your html as

<form method="POST" enctype="multipart/form-data">
        {% csrf_token %}
        {{form.media}}
        {{form.as_p}}
    <button type="submit" name='mybtn'>Submit</button>
      </form>
nofoobar
  • 2,826
  • 20
  • 24
-1

Try to add this script at the bottom of your template

<script>
    $(function () {
        CKEDITOR.replace('id_content', {
            toolbar: 'Basic'
        });
    });
</script>

When you use coeditor from admin interface (I guess through suit-ckeditor) you implicit use this render function for your text area widget:

def render(self, name, value, attrs=None):
    output = super(CKEditorWidget, self).render(name, value, attrs)
    output += mark_safe(
        '<script type="text/javascript">CKEDITOR.replace("%s", %s);</script>'
        % (name, json.dumps(self.editor_options)))
    return output

that basically do the same work.

Salvatore Avanzo
  • 2,656
  • 1
  • 21
  • 30