问题背景
在Django后台的使用admin view绑定model后,可以很方便的通过网页对底层的数据表进行增删查改操作。
在实际工作中有一些数据字段会存储了json或者其他包含换行符、空格符的文本内容,这些文本内容在记录编辑详情页是能正常显示换行、空格的,如下:
但是在changelist页面则会省略所有空格、换行,导致可读性较差,如下:
原因
究其原因,其实是因为在编辑详情页面,存放文本的标签是textarea,在该标签中的文本内容并不会忽略换行、空格字符,通过使用浏览器开发者工具可以看到如下代码:
<textarea name=\"lang_content\" cols=\"40\" rows=\"10\" class=\"vLargeTextField\" required=\"\" id=\"id_lang_content\">{
\"en\": \"this is a content\",
\"zh-hant\": \"這是默認正文內容\"
}</textarea>
而在changelist页面,默认使用的是直接就是td标签,即直接放入一个表单元格之中,这时根据HTML标准会将所有连续的空格、换行符均处理为单个空格:
<td class=\"field-lang_content\">{
\"en\": \"this is a content\",
\"zh-hant\": \"這是默認正文內容\"
}</td>
解决方案
以一个简单的test_record table的admin view为例。
表结构:
CREATE TABLE `test_table` (
`id` bigint(11) unsigned NOT NULL AUTO_INCREMENT COMMENT \'自增主键\',
`title` varchar(255) NOT NULL DEFAULT \'0\',
`content` varchar(255) NOT NULL,
`lang_content` text NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
models.py:
# coding=utf-8
from django.db import models
class TestRecord(models.Model):
class Meta:
db_table = \"test_record\"
db_tablespace = \'test_db\'
id = models.AutoField(primary_key=True, verbose_name=\"id\")
title = models.CharField(max_length=255)
content = models.CharField(max_length=255)
lang_content = models.TextField()
admin.py
from django.contrib import admin
from django.utils.html import format_html
from .models import TestRecord
@admin.register(TestRecord)
class TestRecordAdmin(admin.ModelAdmin):
list_display = (\'id\', \'title\', \'content\', \'lang_content\', \'lang_content_view\')
使用list_editable
将lang_content放入list_editable,如下:
list_editable = (\'lang_content\', )
这样在changelist页面,将使用textarea标签修饰lang_content内容,于是空格、换行符就能够正确显示:
同时在changelist页面将可以直接编辑lang_content字段,无法满足只希望该字段在changelist页面可读,而不可编辑的需求,相当于是把编辑功能和显示功能强制绑定无法分离,缺乏灵活性。
使用format_html--满足只读需求
在django.utils.html中提供了一个format_html函数,该函数可用于将所有输出内容按HTML格式转义渲染。
于是可以通过在admin class中定义一个专门负责展示lang_content内容的实例方法,将lang_content内容用pre或textarea标签包裹,而后经过format_html转义后返回。此方法更加灵活,还可通过调整标签各属性定制输出效果--比如设置高度(rows)、宽度(cols)等。
代码如下所示
def lang_content_view(self, obj):
# return format_html(\'<textarea cols=40 rows={} readonly>{}</textarea>\', obj.lang_content.count(\'\\n\')+1, obj.lang_content)
return format_html(\'<pre>{}</pre>\', obj.lang_content)
显示效果如下:
对应网页代码如下:
<td class=\"field-lang_content_view\"><pre>{
\"en\": \"this is a content\",
\"zh-hant\": \"這是默認正文內容\"
}</pre></td>
转载请注明出处,原文地址:https://www.cnblogs.com/AcAc-t/p/django_admin_changelist_textfield_newline_display.html
来源:https://www.cnblogs.com/AcAc-t/p/django_admin_changelist_textfield_newline_display.html
图文来源于网络,如有侵权请联系删除。