简体   繁体   English

django-ckeditor 模态形式不会更改 POST 上的数据

[英]django-ckeditor modal form does not change data on POST

I have a django project using django-ckeditor.我有一个使用 django-ckeditor 的 django 项目。 I use HTMX to create a bootstrap modal to show my edit form.我使用 HTMX 创建引导模式来显示我的编辑表单。 It renders correctly (I did add the ckeditor.js files at the end of the body in base.html).它呈现正确(我确实在 base.html 的主体末尾添加了 ckeditor.js 文件)。 If I call my form by going to localhost/1/update, change the RTF value, and click save, it works fine.如果我通过转到 localhost/1/update 调用我的表单,更改 RTF 值,然后单击保存,它工作正常。 But rendering it in the modal form and clicking save, the form.has_changed() returns false.但是以模态形式呈现并单击保存,form.has_changed() 返回 false。 If I edit another field and it saves, the value of RTF does NOT change.如果我编辑另一个字段并保存,RTF 的值不会改变。 It seems like the POST does not include the changed value for the CKEditor field. POST 似乎不包含 CKEditor 字段的更改值。

I've tried to reduce the code below to make it as short as possible.我试图减少下面的代码以使其尽可能短。

My model:我的model:

class MyModel(models.Model):    
    name = models.CharField(max_length=50)
    description = models.CharField(max_length=150)
    comment = RichTextField(blank=True, null=True)

    def __str__(self):
        return f'{self.name} - {self.description}'

My form:我的表格:

class MyForm(forms.ModelForm):
    class Meta:
        model = MyModel
        fields = (
            'name',
            'description',
            'comment',
        )

My View我的看法

def update_data(request, pk):
    model = MyModel.objects.get(id=pk)
    form = MyForm(request.POST or None, instance=model)

    if request.method == "POST":
        if form.is_valid():
            print(form.has_changed())
            form.save()
            return redirect("detail-form", pk=model.id)

My HTML#1 - I click on the update button to open the modal我的 HTML#1 - 我点击更新按钮打开模式

{% extends "layouts/base.html" %}

{% load static %}

{% block content %}
<main>
    <div class="section section-md pt-4">
        <div class="container">
            <table class="table">
                <thead>
                    <tr>
                        <th>Name</th>
                        <th>Description</th>
                        <th></th>
                    </tr>
                </thead>
                <tbody id="myforms">
                    {% for entry in entries %}

                    <tr id="entryform_{{entry.id}}">
                        <td>
                            <h4 class="h5">{{ entry.name }}</h4>
                        </td>
                        <td>
                            <h4 class="h5">{{ entry.description }}</h4>
                        </td>
                        <td style="width: 200px">
                            <button hx-get="{% url 'update-entry' entry.id %}" hx-swap="outerHTML"
                            class="inline-flex items-center px-3 py-2 border border-transparent text-sm leading-4 font-medium rounded-md text-indigo-700 bg-indigo-100 hover:bg-indigo-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
                                Update
                            </button>
                        </td>
                    </tr>
                    {% endfor %}
                </tbody>
            </table>
        </div>
    </div>

    <div id="modals-here"></div>
</main>

{% endblock content %}

{% block javascripts %}
<script>
function closeModal() {
    var container = document.getElementById("modals-here")
    var backdrop = document.getElementById("modal-backdrop")
    var modal = document.getElementById("modal")

    modal.classList.remove("show")
    backdrop.classList.remove("show")

    setTimeout(function() {
        container.removeChild(backdrop)
        container.removeChild(modal)
    }, 200)
}
</script>
{% endblock javascripts %}

and then the last html, the model form.然后是最后一个 html,即 model 表格。 Notice that I did add the {{ form.media }}请注意,我确实添加了 {{ form.media }}

<div id="modal-backdrop" class="modal-backdrop fade show" style="display:block;">    </div>
<div id="modal" class="modal fade show" tabindex="-1" style="display:block;">
    <div class="modal-dialog modal-dialog-centered">
      <div class="modal-content">
        <div class="modal-body">
            <form method="post">
                {% csrf_token %}
        
                {{ form.media }}
                {{ form.as_p|safe }}
                <button type="submit" hx-post="{% url 'update-data' entry.id %}" hx-target="#entryform_{{entry.id}}" hx-swap="outerHTML"
                    class="btn btn-primary" onclick="closeModal()">
                    Submit
                </button>
            </form>
        </div>
      </div>
    </div>
  </div>

Any advice?有什么建议吗? My gut feel says it has something to do with the fact that the editor only gets loaded after the page has already loaded.我的直觉说这与编辑器仅在页面加载后才加载这一事实有关。 If I recall I had a similar issue years ago with a JS date picker.如果我记得几年前我遇到过类似的 JS 日期选择器问题。 I can't recall for the life of me how I fixed it then.我这辈子都想不起来我是怎么修好的。

The problem was not with the modal code.问题不在于模态代码。 HTMX caused the issue. HTMX 导致了这个问题。 This would always be the issue when using HTMX with RTF editors, and I think this solution would work for all cases.在将 HTMX 与 RTF 编辑器一起使用时,这始终是个问题,我认为此解决方案适用于所有情况。 I found a similar issue with tinyMCE with a resolution for tinyMCE here .我在 tinyMCE 上发现了类似的问题,解决方案为 tinyMCE here My implementation with CKEditor is the code as follows:我用CKEditor实现的代码如下:

<div id="modal-backdrop" class="modal-backdrop fade show" 
style="display:block;">    </div>
<div id="modal" class="modal fade show" tabindex="-1" style="display:block;">
    <div class="modal-dialog modal-dialog-centered">
      <div class="modal-content">
        <div class="modal-body">
            <form method="post">
                {% csrf_token %}
    
                {{ form.media }}

                <script>
                    document.body.addEventListener('htmx:configRequest', (event) => {
                        var element = new CKEDITOR.dom.element( document.getElementById( '{{ form.comment.id_for_label }}' ) );
                        event.detail.parameters['{{ form.comment.html_name }}'] = element.getEditor().getData();        
                    })
                </script>
                {{ form.as_p|safe }}
                <button type="submit" hx-post="{% url 'update-data' entry.id %}" hx-target="#entryform_{{entry.id}}" hx-swap="outerHTML"
                    class="btn btn-primary" onclick="closeModal()">
                    Submit
                </button>
            </form>
        </div>
      </div>
    </div>
  </div>

It might not be the best spot to put the script, but it works fine there.它可能不是放置脚本的最佳位置,但它在那里工作得很好。 This spot also makes it possible to make it more generic using form tags.这个 spot 还可以使用表单标签使其更通用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM