Code前端首页关于Code前端联系我们

Django admin实现文本字段字段变更列表页面换行和空格正常显示

terry 2年前 (2023-09-24) 阅读数 68 #后端开发

问题背景

使用admin视图在Django后台绑定模型后,可以方便的进行底层的增删改查修改通过网页的数据表。
在实际工作中,有些数据字段存储的是json或者其他包含换行符和空格的文本内容。该文本内容在编辑信息页面上正常情况下可能会出现换行和空格,如下:
Django admin实现TextField字段changelist页面换行、空格正常显示

但在更改列表页面上,所有空格和换行都会被省略,导致可读性较差,如下:
Django admin实现TextField字段changelist页面换行、空格正常显示

原因

原因其实是因为在编辑详情页中,存放文本的标签是文本区域,该标签的文本内容不会忽略换行符和空格。使用浏览器的开发者工具,可以看到如下代码:

<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 表的简单管理视图为例。
表结构:

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中,如下:标签将用于更改lang_content内容,因此空格和行可以正确显示break:
Django admin实现TextField字段changelist页面换行、空格正常显示

同时lang_content字段可以直接在changelist页面编辑,无法满足该字段在changelist页面只读但不可编辑的要求,相当于编辑功能和显示功能强行绑定,无法分开,缺乏灵活性。

使用format_html——满足只读要求

django.utils.html中提供了format_html函数,可用于转义并渲染所有HTML格式的输出内容。
所以可以在admin类中定义一个专门负责显示lang_content内容的实例方法,将lang_content内容用pre或textarea标签包裹起来,然后在format_html转义之后返回。这种方法比较灵活,还可以通过调整标签的属性来自定义输出效果——比如设置高度(行)、宽度(列)等。
代码如下

    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)

显示效果如下:
Django admin实现TextField字段changelist页面换行、空格正常显示
对应网页代码如下:

<td class="field-lang_content_view"><pre>{
  "en": "this is a content",
  "zh-hant": "這是默認正文內容"
}</pre></td>

版权声明

本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

热门