假设我在 1 Db 中有 10 个表,表名不同,数据也不同,但表的结构是相同的。然后我还有 1 个表,用于收集所有表名和该表的创建日期。
例子:
PrimaryTable
table_name_1
table_name_2
....
table_name_10
以及所有表的结构示例:
class PrimaryTable(models.Model):
name = models.CharField(db_column='Name', unique=True, max_length=100)
date = models.CharField(db_column='Date', max_length=100)
class Meta:
managed = True
db_table = 'Primary Table'
def __str__(self):
return self.name
class table_name_1(models.Model):
title = models.TextField(db_column='Title', blank=True, null=True)
url = models.CharField(db_column='Url', unique=True, max_length=250, blank=True,
null=True)
description = models.TextField(db_column='Description', blank=True, null=True)
created_at = models.DateTimeField(db_column='Created_at')
class table_name_2(models.Model):
title = models.TextField(db_column='Title', blank=True, null=True)
url = models.CharField(db_column='Url', unique=True, max_length=250, blank=True,
null=True)
description = models.TextField(db_column='Description', blank=True, null=True)
created_at = models.DateTimeField(db_column='Created_at')
等等……
我只想创建一个包含所有具有相同结构的表的类,并在我从 PrimaryTable 中选择表时调用它。
我不想每次创建表时都使用“python manage.py inspectdb > models.py”。我想在创建新表时立即访问它。
最佳答案
您可以将模型字段定义为字典:
fields = dict(
title = models.TextField(db_column='Title', blank=True, null=True),
url = models.CharField(db_column='Url', unique=True, max_length=250, blank=True, null=True),
description = models.TextField(db_column='Description', blank=True, null=True),
created_at = models.DateTimeField(db_column='Created_at'),
)
然后您可以为其动态创建和运行迁移:
from django.db import connection, migrations, models
from django.db.migrations.executor import MigrationExecutor
def create_table(table_name, model_fields, app_label):
class Migration(migrations.Migration):
initial = True
dependencies = []
operations = [
migrations.CreateModel(
name=table_name,
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
] + [(k, field) for k,field in model_fields.items()],
options={
'db_table': table_name,
},
),
]
executor = MigrationExecutor(connection)
migration = Migration(table_name, app_label)
with connection.schema_editor(atomic=True) as schema_editor:
migration.apply(executor._create_project_state(), schema_editor)
然后您可以使用动态模型创建来访问表中的数据:
from django.db import models
def create_model(name, fields=None, app_label=None, module='', options=None, admin_opts=None):
"""
Create specified model
"""
class Meta:
db_table = name
if app_label:
# app_label must be set using the Meta inner class
setattr(Meta, 'app_label', app_label)
# Update Meta with any options that were provided
if options is not None:
for key, value in options.iteritems():
setattr(Meta, key, value)
# Set up a dictionary to simulate declarations within a class
attrs = {'__module__': module, 'Meta': Meta}
# Add in any fields that were provided
if fields:
attrs.update(fields)
# Create the class, which automatically triggers ModelBase processing
model = type(name, (models.Model,), attrs)
return model
希望您能大致了解一下。 我从使用 Django 2 的项目中获取了代码(类似的代码用于为每个上传的 CSV 文件创建表格,每个上传的 CSV 的列和名称存储在类似于您的 PrimaryTable 的表格中)。
关于python - 动态模型 django,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46213379/