我的目的是动态生成Django模型 我使用以下代码创建模型。
def create_model(name, fields=None, app_label='', module='', options=None, admin_opts=None):
class Meta:
# Using type('Meta', ...) gives a dictproxy error during model creation
pass
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)
# Create an Admin class if admin options were provided
if admin_opts is not None:
class Admin(admin.ModelAdmin):
pass
for key, value in admin_opts:
setattr(Admin, key, value)
admin.site.register(model, Admin)
return model
然后我知道我需要从模型生成sql并同步到数据库中 我使用以下代码:
def install(custom_model):
from django.core.management import color
from django.db import connection
from django.db.backends.base import schema
style = color.no_style()
cursor = connection.cursor()
statements, pending = connection.creation.sql_create_model(custom_model, style)
for sql in statements:
cursor.execute(sql)
然而,它告诉我,答案 0 :(得分:1)
我为此找到了解决方案
from django.db import connection
with connection.schema_editor() as editor:
editor.create_model(model)
注意如果您在Meta中具有unique_together,则必须使用“ with”语句,因为在__enter__方法中定义了deferred_sql,否则您将获得没有属性“ deferred_sql”的异常。请检查backends / base / schema.py中的django'BaseDatabaseSchemaEditor'代码
class BaseDatabaseSchemaEditor:
... ...
def __enter__(self):
self.deferred_sql = []
if self.atomic_migration:
self.atomic = atomic(self.connection.alias)
self.atomic.__enter__()
return self
... ...
def create_model(self, model):
... ...
# Add any unique_togethers (always deferred, as some fields might be
# created afterwards, like geometry fields with some backends)
for fields in model._meta.unique_together:
columns = [model._meta.get_field(field).column for field in fields]
self.deferred_sql.append(self._create_unique_sql(model, columns))
... ...