让 Django 为 TextField 而不是 textarea 构建 contenteditable div

Posted

技术标签:

【中文标题】让 Django 为 TextField 而不是 textarea 构建 contenteditable div【英文标题】:Make Django build contenteditable div for TextField instead of textarea 【发布时间】:2017-11-10 10:20:09 【问题描述】:

在我的 Django 1.10 项目中,我有一个模型:

class Contact(models.Model):
    notes = models.TextField()

...和模型形式:

class ContactForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):    
        super(ContactForm, self).__init__(*args, **kwargs)   
        for field_name, field in self.fields.items():
            field.widget.attrs['class'] = 'form-control input-sm plain'
            if field.required == True: 
                field.widget.attrs['required'] = ''

    class Meta:
        model = Contact
        fields = ('notes',)

对此我有两个问题:

    我可以让 Django 使用 contenteditable=true 而不是 textarea 将 notes 字段呈现为 div 吗? 如果是,如何自动化 form.save() 方法?

第二个问题有点含糊,所以如果能提供关于第一个问题的提示,我将不胜感激。我已阅读文档,但找不到相关部分:(

【问题讨论】:

我知道我来晚了,但是当我也需要这个问题的确切答案时,我在网上找到了这篇文章 | Article 【参考方案1】:

问题一:使用特定的 html 标签渲染字段

在这种情况下,<div contenteditable="true">...</div>

您可以自定义用于呈现表单字段的小部件。基本上,当您声明该字段时,您必须传递参数widget=TheWidgetClass。 Django 有很多builtin widgets 可以使用。但是你也可以定义你自己的。要知道如何,您会在 Internet 上找到许多资源。只需在搜索引擎或 SO 上搜索“django create custom widget”。可能的答案:Django: How to build a custom form widget?

由于 Django 没有提供任何关于如何创建自定义小部件的官方文档,最聪明的方法是创建一个继承 Django's TextArea 的类并使用基于 original one 的自定义 html 模板。

问题 2:使用这种自定义小部件自动化 form.save() 方法

基本上,您必须确保 div 标签的值与其他输入值一起发送到表单的目标视图,在 POST 数据中。换句话说,您必须确保 div 的内容与任何表单域的内容一样。 也许this SO question 可以帮助您:一种解决方案可能是在用户单击提交按钮时使用 javascript 将 div 的内容复制到表单中隐藏的 textarea 标记。

祝你好运;)

【讨论】:

【参考方案2】:

第一个可以使用 jquery 来完成。由于 django 将使用 id='id_notes' 加载 textarea。所以之后你可以选择元素并做任何你想做的事情。

在第二个中,您可以通过在 forms.py 中编写自己的保存函数来重新定义保存方法。这是一个用于 url 缩短器的 example。 Save 方法基本上定义了在将某些内容提交到数据库时要执行的操作。

【讨论】:

以上是关于让 Django 为 TextField 而不是 textarea 构建 contenteditable div的主要内容,如果未能解决你的问题,请参考以下文章

让 Django 仅返回存储为 models.TextField() 的文本的前 50 个字符

Django 2.0 - iexact 转换为 LIKE 而不是 ILIKE

Django CharField 不默认为空字符串

将TextField限制为N个单词,而不是N个字符

ActionScript 3 将TextField限制为N个单词而不是N个字符

将值呈现为文本而不是 Django 表单中的字段