加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

django 动态创建一个模型的多个table name, 并通过 Django ORM

发布时间:2020-12-15 17:14:07 所属栏目:大数据 来源:网络整理
导读:动态创建table, 并通过 Django ORM 操作. 动态的创建表 动态的创建模型其实就是在运行时生成 Model 类, 这个可以通过函数实现, 通过传参(今天的日期,如: 20181211),然后生成新的模型类, Meta 中的 db_table 为log_20181211. def?get_log_model(prefix):

动态创建table, 并通过 Django ORM 操作.

动态的创建表

动态的创建模型其实就是在运行时生成 Model 类, 这个可以通过函数实现, 通过传参(今天的日期,如: 20181211),然后生成新的模型类, Meta 中的 db_table 为log_20181211.

def?get_log_model(prefix):
????table_name?=?'log_%s'?%?str(prefix)

????LOG_LEVELS?=?(
????????(0,?'DEBUG'),????????(10,?'INFO'),????????(20,?'WARNING'),????)

????class?LogMetaclass(models.base.ModelBase):
????????def?__new__(cls,?name,?bases,?attrs):
????????????name?+=?'_'?+?prefix??#?这是Model的name.
????????????return?models.base.ModelBase.__new__(cls,?attrs)

????class?Log(models.Model):
????????__metaclass__?=?LogMetaclass
????????level?=?models.IntegerField(choices=LOG_LEVELS)
????????msg?=?models.TextField()
????????time?=?models.DateTimeField(auto_now=True,?auto_now_add=True)

????????@staticmethod
????????def?is_exists():
????????????return?table_name?in?connection.introspection.table_names()

????????class?Meta:
????????????db_table?=?table_name

????return?Log

可以看到, 通过函数生成不同的 Log Class. 注意LogMetaclass和__metaclass__,元类可以在运行时改变模型的名字,table 的名称我们可以通过db_table定义,类的名称可以通过覆盖元类的方法定义。

print?cls.__name__
Log_20181211
print?cls._meta.db_table
log_20181211

使用

使用直接通过函数, 获取当前日期的 Log 模型, 然后通过is_exists判读表是否创建, 没有创建则创建对应的表.

def?index(request):
????today?=?date.today().strftime("%Y%m%d")

????#?RuntimeWarning:?Model?'__main__.logclasslog_'?was?already?registered.
????#?Reloading?models?is?not?advised?as?it?can?lead?to?inconsistencies
????#?most?notably?with?related?models.
????#?如上述警告所述,?Django?不建议重复加载?Model?的定义.
????#?作为?demo?可以直接通过get_log_model获取,无视警告.
????#?所以这里先通过?all_models?获取已经注册的?Model,????#?如果获取不到,?再生成新的模型.
????try:
????????cls?=?apps.get_model('__main__',?'Log_%s'?%?today)
????except?LookupError:
????????cls?=?get_log_model(today)

????if?not?cls.is_exists():
????????with?connection.schema_editor()?as?schema_editor:
????????????schema_editor.create_model(cls)

????log?=?cls(level=10,?msg="Hello")
????log.save()

????return?HttpResponse('<h1>%s</h1>'?%?cls._meta.db_table)

上面获取 cls 部分, 这里的代码先通过apps的已经注册的 all_models 获取,否则一个模型的第二次执行定义代码就会抛出RuntimeWarning警告,在模型的初始化函数都会注册此模型,最好不要重复注册. 先通过 apps.get_model 获取这个模型, 如果没有获取到则通过get_log_model初始化新的模型. 这样做更加稳妥一点.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读