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了,