Files
jyls_django/analyze_models.py
2026-01-27 00:23:31 +08:00

145 lines
5.2 KiB
Python

"""
分析所有模型类,生成字段列表报告
用于对比数据库字段和模型类字段
"""
import os
import sys
import django
# 设置 Django 环境
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'jyls_django.settings')
django.setup()
from django.apps import apps
from django.db import models
def analyze_model(model):
"""分析单个模型,返回字段信息"""
fields_info = {
'model_name': model.__name__,
'table_name': model._meta.db_table,
'fields': [],
'm2m_fields': [],
'foreign_keys': []
}
for field in model._meta.get_fields(include_parents=False):
# 多对多关系
if isinstance(field, models.ManyToManyField):
fields_info['m2m_fields'].append({
'name': field.name,
'related_model': field.related_model.__name__ if field.related_model else None,
'through_table': field.remote_field.through._meta.db_table if hasattr(field.remote_field, 'through') else None
})
continue
# 跳过反向关系
if getattr(field, 'auto_created', False):
continue
# 跳过没有 column 属性的字段(反向关系)
if not hasattr(field, 'column'):
continue
field_info = {
'name': field.name,
'column': field.column,
'type': type(field).__name__,
'null': getattr(field, 'null', False),
'blank': getattr(field, 'blank', False),
'max_length': getattr(field, 'max_length', None),
'default': str(getattr(field, 'default', 'NOT_PROVIDED')),
}
# 外键
if isinstance(field, models.ForeignKey):
field_info['related_model'] = field.related_model.__name__ if field.related_model else None
fields_info['foreign_keys'].append(field_info)
else:
fields_info['fields'].append(field_info)
return fields_info
def main():
print('=' * 80)
print('模型类字段分析报告')
print('=' * 80)
apps_to_check = [
apps.get_app_config('User'),
apps.get_app_config('finance'),
apps.get_app_config('business')
]
all_models_info = []
for app_config in apps_to_check:
print(f'\n\n应用: {app_config.name}')
print('=' * 80)
models_to_check = app_config.get_models()
for model in models_to_check:
info = analyze_model(model)
all_models_info.append(info)
print(f'\n模型: {info["model_name"]}')
print(f'表名: {info["table_name"]}')
print('-' * 80)
# 普通字段
if info['fields']:
print('\n普通字段:')
for field in info['fields']:
null_str = 'NULL' if field['null'] else 'NOT NULL'
max_len_str = f", max_length={field['max_length']}" if field['max_length'] else ''
default_str = f", default={field['default']}" if field['default'] != 'NOT_PROVIDED' else ''
print(f" - {field['column']} ({field['type']}{max_len_str}, {null_str}{default_str})")
# 外键
if info['foreign_keys']:
print('\n外键字段:')
for field in info['foreign_keys']:
null_str = 'NULL' if field['null'] else 'NOT NULL'
related = field.get('related_model', 'Unknown')
print(f" - {field['column']} (ForeignKey -> {related}, {null_str})")
# 多对多关系
if info['m2m_fields']:
print('\n多对多关系:')
for field in info['m2m_fields']:
related = field.get('related_model', 'Unknown')
through = field.get('through_table', 'auto')
print(f" - {field['name']} (ManyToMany -> {related}, through={through})")
# 生成汇总报告
print('\n\n' + '=' * 80)
print('汇总报告')
print('=' * 80)
print(f'\n总共检查了 {len(all_models_info)} 个模型:')
for info in all_models_info:
field_count = len(info['fields']) + len(info['foreign_keys'])
m2m_count = len(info['m2m_fields'])
print(f" - {info['model_name']} ({info['table_name']}): {field_count} 个字段, {m2m_count} 个多对多关系")
# 检查是否有 User 模型缺少 approvers_order 字段
print('\n\n' + '=' * 80)
print('特殊检查: User 模型字段')
print('=' * 80)
user_model = apps.get_model('User', 'User')
user_info = analyze_model(user_model)
has_approvers_order = any(f['name'] == 'approvers_order' for f in user_info['fields'])
if not has_approvers_order:
print('\n⚠️ 发现: User 模型没有 approvers_order 字段')
print(' 这可能导致入职/离职登记的审批流程无法正确获取审核人列表')
print(' 建议: 从 Approval.content 字段解析审核人列表(已在代码中实现)')
else:
print('\n✅ User 模型有 approvers_order 字段')
if __name__ == '__main__':
main()