You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python实现Django动态模型生成方案咨询(替代C# CodeDom)

Python 替代 CodeDom 生成 Django REST Framework 模型方案

核心方向

优先选择代码生成(生成可维护的物理模型文件),适合正式项目;若仅需运行时动态加载类,可采用动态类创建,适合临时测试场景。

推荐工具与实现

1. Jinja2(灵活可控的代码生成方案)

通过模板引擎读取JSON配置,渲染生成标准Django模型文件,可维护性强。

JSON配置示例

{
  "models": [
    {
      "class_name": "Book",
      "fields": [
        {"name": "title", "type": "CharField", "params": {"max_length": 200, "verbose_name": "书名"}},
        {"name": "author", "type": "ForeignKey", "params": {"to": "Author", "on_delete": "CASCADE", "verbose_name": "作者"}},
        {"name": "publication_date", "type": "DateField", "params": {"null": true, "blank": true, "verbose_name": "出版日期"}}
      ],
      "meta": {"verbose_name": "图书", "verbose_name_plural": "图书"}
    },
    {
      "class_name": "Author",
      "fields": [
        {"name": "name", "type": "CharField", "params": {"max_length": 100, "verbose_name": "姓名"}},
        {"name": "email", "type": "EmailField", "params": {"unique": true, "verbose_name": "邮箱"}}
      ]
    }
  ]
}

实现步骤

  1. 安装依赖
pip install jinja2
  1. 创建模板文件(model_template.py.j2)
from django.db import models

{% for model in models %}
class {{ model.class_name }}(models.Model):
    {% for field in model.fields %}
    {{ field.name }} = models.{{ field.type }}(
        {% for key, value in field.params.items() %}
        {{ key }}={{ 'models.' + value if key == 'on_delete' else (value|string if value is string else value) }}{% if not loop.last %},{% endif %}
        {% endfor %}
    )
    {% endfor %}

    class Meta:
        {% if model.meta.verbose_name %}
        verbose_name = "{{ model.meta.verbose_name }}"
        {% endif %}
        {% if model.meta.verbose_name_plural %}
        verbose_name_plural = "{{ model.meta.verbose_name_plural }}"
        {% endif %}

    def __str__(self):
        return self.{{ model.fields[0].name }} if {{ model.fields|length > 0 }} else super().__str__()
{% endfor %}
  1. 编写渲染脚本
import json
from jinja2 import Environment, FileSystemLoader

# 加载配置文件
with open('model_config.json', 'r', encoding='utf-8') as f:
    config = json.load(f)

# 初始化模板环境
env = Environment(loader=FileSystemLoader('.'))
template = env.get_template('model_template.py.j2')

# 生成模型文件
output_content = template.render(models=config['models'])
with open('generated_models.py', 'w', encoding='utf-8') as f:
    f.write(output_content)

2. 动态类创建(运行时生成)

无需生成物理文件,直接用type()构造模型类,适合临时场景。

import json
from django.db import models

def build_dynamic_model(class_name, fields, meta=None):
    field_attrs = {}
    # 构建字段
    for field in fields:
        field_cls = getattr(models, field['type'])
        field_params = field['params'].copy()
        # 处理models常量参数(如CASCADE)
        if 'on_delete' in field_params:
            field_params['on_delete'] = getattr(models, field_params['on_delete'])
        field_attrs[field['name']] = field_cls(**field_params)
    
    # 构建Meta类
    meta_attrs = meta or {}
    field_attrs['Meta'] = type('Meta', (), meta_attrs)
    
    # 构建__str__方法
    def model_str(self):
        return getattr(self, fields[0]['name'], super().__str__()) if fields else super().__str__()
    field_attrs['__str__'] = model_str
    
    # 创建并返回模型类
    return type(class_name, (models.Model,), field_attrs)

# 加载配置并生成模型
with open('model_config.json', 'r', encoding='utf-8') as f:
    config = json.load(f)

for model_cfg in config['models']:
    dynamic_model = build_dynamic_model(
        model_cfg['class_name'],
        model_cfg['fields'],
        model_cfg.get('meta')
    )
    # 绑定到指定Django应用
    dynamic_model._meta.app_label = 'your_app_name'

方案对比

  • Jinja2代码生成:生成的代码可编辑、易调试,支持版本控制,适合长期维护的项目。
  • 动态类创建:无物理文件,适合快速测试或动态调整需求,但不利于后期扩展和问题排查。

注意事项

  1. JSON配置中,Django常量(如CASCADE)需以字符串形式存储,渲染时转成实际引用。
  2. 生成的模型文件需添加到Django应用的INSTALLED_APPS配置中,或直接导入到models.py。
  3. 模型生成后,需执行python manage.py makemigrations和python manage.py migrate同步数据库。

内容的提问来源于stack exchange,提问作者Rad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 05:43:24