python - 动态模型 django

标签 python mysql django

假设我在 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/

相关文章:

python - activestate pythonwin 缺少导入模块?

python - 在 Heroku-16 堆栈上安装 GCC (gfortran)

python - 使用 python 导入我的数据库连接

django - 如何在条件下使用 ManyToManyField

python - SUDS 或 SOAPpy : google app engine python

python - Funkload 和 cookie

python - 从 docx 文件中删除所有图像

python - Jupyter Notebook 无法打包 folium

javascript - 使用填充的下拉列表填充文本框

MySQL别名问题