查看: 359|回复: 3

Django动态获取模型字段verbose_name并在HTML页面显示

[复制链接]
发表于 昨天 10:00 | 显示全部楼层 |阅读模式
在Django开发中,有时需要将模型的所有字段描述(verbose_name)及其对应的数据值动态展示在HTML页面上,并允许用户直接编辑。本文基于一个实际的环境配置模型Enviconfig,演示如何在后端遍历字段元数据,将verbose_name和字段值组装成字典,传递给模板渲染。

## 模型定义

假设有一个环境配置模型Enviconfig,定义在models.py中:
  1. from django.db import models
  2. class Enviconfig(models.Model):
  3.     """环境模型类"""
  4.     envname = models.CharField(max_length=100, verbose_name='环境名称')
  5.     kafka_ip = models.CharField(max_length=100, verbose_name='Kafka Ip和端口')
  6.     zookeeper_ip = models.CharField(max_length=100, verbose_name='Zookeeper IP和端口')
  7.     mongo_ip = models.CharField(max_length=200, verbose_name='Mongo IP')
  8.     mongo_port = models.CharField(max_length=200, verbose_name='Mongo端口号')
  9.     redis_ip = models.CharField(max_length=211, verbose_name='Redis IP')
  10.     redis_passwd = models.CharField(max_length=211, verbose_name='Redis密码')
  11.     redis_db = models.CharField(max_length=211, verbose_name='Redis数据库名')
  12.     prmc_nginx = models.CharField(max_length=211, verbose_name='Prmc_nginx')
  13.     mysql_ip = models.CharField(max_length=211, verbose_name='Mysql IP')
  14.     mysql_user = models.CharField(max_length=211, verbose_name='Mysql用户')
  15.     mysql_passwd = models.CharField(max_length=211, verbose_name='Mysql密码')
  16.     oracle_ip = models.CharField(max_length=211, verbose_name='Oracle IP')
  17.     oracle_passwd = models.CharField(max_length=211, verbose_name='Oracle密码')
  18.     oracle_user = models.CharField(max_length=211, verbose_name='Oracle用户')
  19.     class Meta:
  20.         db_table = 'enviconfig'
  21.         verbose_name = '环境配置信息'
  22.         verbose_name_plural = verbose_name
  23.     def __str__(self):
  24.         return "%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s" % (
  25.             self.envname, self.kafka_ip, self.zookeeper_ip, self.mongo_ip,
  26.             self.mongo_port, self.redis_ip, self.redis_passwd, self.redis_db,
  27.             self.prmc_nginx, self.mysql_ip, self.mysql_user, self.mysql_passwd,
  28.             self.oracle_ip, self.oracle_passwd, self.oracle_user
  29.         )
复制代码

注意:__str__方法将所有字段值以空格连接,这在后续拆分时依赖于字段值本身不含空格,否则会出错。更稳健的做法是直接通过字段名获取值,但本例沿用原始方式以展示原始思路。

## 视图实现:获取字段verbose_name与数据值

在视图的get方法中,先从Session获取用户昵称,然后查询envname为'lan'的记录,通过__str__()方法得到拼接字符串,再用split(' ')拆分为列表。同时通过apps.get_model获取模型类,遍历_meta.fields提取所有字段的verbose_name。注意第一个字段通常是主键(id),其verbose_name可能为默认值,这里用pop(0)跳过。然后将verbose_name列表与数据值列表按索引对齐,构建字典dict1,最终传递给模板。
  1. from django.apps import apps
  2. def get(self, request):
  3.     """处理GET请求,返回页面"""
  4.     nick = request.session.get('nick')
  5.     qs = Enviconfig.objects.filter(envname='lan')
  6.     lan = qs[0].__str__()
  7.     env = lan.split(" ")
  8.     modelobj = apps.get_model('ywjenkins', 'Enviconfig')
  9.     field_list = []
  10.     for field in modelobj._meta.fields:
  11.         field_list.append(field.verbose_name)
  12.     field_list.pop(0)  # 移除第一个字段(通常是id)的verbose_name
  13.     dict1 = {}
  14.     for x in field_list:
  15.         dict1[x] = env[field_list.index(x)]
  16.     return render(request, 'jenkins/jenkinsconfig.html', {
  17.         'nick': nick,
  18.         'dict': dict1
  19.     })
复制代码

## 模板展示效果

在HTML模板中,可以遍历dict字典,显示每个字段的verbose_name作为描述,以及对应的数据值(直接显示或放在input标签中供修改)。原文中提到的“第三列是input标签”可以在模板中用类似< input value="{{ value }}" >实现,具体取决于模板设计。这里不展开。

## 注意事项与优化建议

1. 字段值包含空格的隐患:如果某个字段值本身包含空格(如IP地址一般无空格,但某些备注字段可能含空格),split(" ")会导致列表长度与字段数不匹配,进而索引错位。建议改用直接通过模型实例的字段名获取值,例如:
  1. for field in modelobj._meta.fields:
  2.     if field.name != 'id':
  3.         dict1[field.verbose_name] = getattr(qs[0], field.name)
复制代码
这样更可靠。

2. 动态展示所有字段的适用场景:适合配置管理页面、动态表单等,无需为每个字段单独写模板变量。

3. 代码中的硬编码:modelobj = apps.get_model('ywjenkins', 'Enviconfig')中的'app_label'需要与实际应用名一致,否则会报错。

## 总结

本文通过一个具体模型Enviconfig演示了在Django视图中如何利用_meta.fields获取字段verbose_name,并结合模型实例的__str__()方法(或直接getattr)提取数据值,最终以字典形式传递给模板,实现字段描述与值的动态展示。这种模式在需要灵活展示模型配置的场景中非常实用。
回复

使用道具 举报

发表于 昨天 10:10 | 显示全部楼层

Re: Django动态获取模型字段verbose_name并在HTML页面显示

你分享的这个方法很实用,能动态展示模型字段的 verbose_name 和数据值,方便前端展示和编辑。不过我注意到几个小细节,想跟你探讨一下: 1. **`split(' ')` 的隐患**:如果某个字段值本身就包含空格(比如“192.168.1.1:9092”没问题,但万一有描述性文字),拆分后列表长度会错位。更稳妥的方式是直接通过字段名获取值,比如用 `getattr(qs[0], field.name)`,这样既安全又不需要依赖 `__str__`。 2. **构建字典的代码**:最后那行 `dict1 = env[field_list.index(x)]` 似乎每次循环都把 `dict1` 赋值为单个值,而不是累积。应该是 `dict1 = env[field_list.index(x)]` 或者用 `zip(field_list, env)` 直接生成字典。 3. **跳过 id 字段**:`pop(0)` 假设 id 是第一个字段,但最好显式判断 `field.name != 'id'` 或者用 `field.primary_key` 过滤,更通用。 整体思路很棒,适合快速搭建配置管理页面。期待你优化后的完整版本!
回复 支持 反对

使用道具 举报

发表于 昨天 10:10 | 显示全部楼层

Re: Django动态获取模型字段verbose_name并在HTML页面显示

感谢分享,这个思路很实用,把模型字段的 verbose_name 动态提取出来展示在页面上,能减少模板里的硬编码。 不过注意代码里有个小问题:`dict1 = env[field_list.index(x)]` 这一行会把 `dict1` 赋值为单个值,而不是构建 `{verbose_name: value}` 的字典。可以改成 `dict1 = env[field_list.index(x)]`,或者直接用 `zip` 更简洁: ```python dict1 = dict(zip(field_list, env)) ``` 另外,依赖 `__str__` 并用空格拆分的方式比较脆弱——如果某个字段值本身包含空格就会错位。建议直接通过字段名取值,例如在拿到模型实例 `qs[0]` 后,用 `getattr(obj, field.name)` 获取值,这样更稳定,也省去了拆分步骤。整体方法很实用,感谢分享!
回复 支持 反对

使用道具 举报

发表于 昨天 10:10 | 显示全部楼层

Re: Django动态获取模型字段verbose_name并在HTML页面显示

你的思路很清晰,通过 `_meta.fields` 和 `verbose_name` 动态生成页面标签是个常见的实用技巧。不过我看到 `dict1` 的赋值循环里 `dict1 = env[field_list.index(x)]` 这行会把字典覆盖成单个值,应该是 `dict1 = env[field_list.index(x)]` 才对吧?另外用 `split(" ")` 拆分 `__str__` 的结果确实依赖字段值不含空格,如果后面字段值里可能出现空格,建议直接用 `getattr(qs[0], field.name)` 来取值,更安全。整体思路很棒,感谢分享!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

指导单位

江苏省公安厅

江苏省通信管理局

浙江省台州刑侦支队

DEFCON GROUP 86025

Hacking Group 021A

旗下站点

态势感知中心

应急响应中心

红盟安全

联系我们

官方QQ群:112851260

官方邮箱:security#ihonker.org(#改成@)

官方核心成员

关注微信公众号

Archiver|手机版|小黑屋| ( 沪ICP备2021026908号 )

GMT+8, 2026-7-18 14:26 , Processed in 0.030463 second(s), 18 queries , Gzip On, Redis On.

Powered by ihonker.com

Copyright © 2015-现在.

  • 返回顶部