django dynamic model

django model

首先对于一个习惯用django model的骚年来说,你肯定对django model自定制用的很熟悉,但突然让你用django dynamic model,也许会有很多人懵逼,然后各种查官网,看论坛,翻源码,终于搞出了。不过对于我们这些新手来说是相当吃力的。现在整理出来方便日后观看。

对于什么是django model 的定义就不多说

create table

在动态创建之前,应该先了解一下makemigrations以及migrate 的源码,先看看他们是如何生成的。下面是自己测试成功代码,仅供参考

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='a',
                fields=[
                    ('title', models.CharField(choices=[('MR', 'Mr.'), ('MRS', 'Mrs.'), ('MS', 'Ms.')], max_length=3)),
                    ('birth_date', models.DateField(blank=True, null=True)),
                ],
            ),
            migrations.CreateModel(
                name='b',
                fields=[
                    ('id', models.AutoField(auto_created=True, serialize=False, verbose_name='ID')),
                    ('name', models.CharField(max_length=100)),
                    ('authors', models.ManyToManyField(to='app.a', related_name='author')),
                ],
            ),
            migrations.CreateModel(
                name='c',
                fields=[
                    ('id', models.AutoField(auto_created=True, serialize=False, verbose_name='ID')),
                    ('name', models.CharField(max_length=32)),
                    ('data', models.CharField(db_index=True, max_length=32)),
                ],
            ),
        ]
    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)

执行代码

    custom_model = create_table('example', fields,
                                 app_label='app',
                              )

注意 fields可自定制

执行成功后,你会发现你的数据表里多了这几个表

此时可不能万事大吉,怎么去操作也是很重要的。

操作danamic model

def get_model(name, fields=None, app_label=None, module='', options=None, admin_opts=None):
    """
    Create specified model
    """
    class Meta:
        db_table = name
    if app_label:
        setattr(Meta, 'app_label', app_label)
    if options is not None:
        for key, value in options.items():
            setattr(Meta, key, value)
    attrs = {'__module__': module, 'Meta': Meta}
    if fields:
        attrs.update(fields)

    model = type(name, (models.Model,), attrs)
    return model

执行 get_model

al = dict(
    title=models.CharField(choices=[('MR', 'Mr.'), ('MRS', 'Mrs.'), ('MS', 'Ms.')], max_length=3),
    birth_date=models.DateField(blank=True, null=True)
)
model_a = get_model('app_a', app_label='app', fields=al)

注意此时al 为你动态创建的model 字段,此时你获取该model时需要将字段传进去

而这此时也只是对单表操作,如果遇到manytomany呢?

那么别急,肯定会有解决的办法

哈哈

 model_a = get_model('app_a', app_label='app', fields=al)
    fields = dict(
        name=models.CharField(max_length=100),
        authors=model_a
    )

    modelb = get_model('app_b', app_label='app', fields=fields)
    obj = modelb.objects.filter(id=1).first()
    print(obj)
    a = obj.authors.objects.values('title')
    print(a)

即:如果你要正向操作,针对上面创建得表,你首先创建a表的类型,然后将a类型作为authors的参数传进去即可。

现在就一切OK了,  

  

  

  

猜你喜欢

转载自www.cnblogs.com/flash55/p/9064241.html