django 动态创建一个模型的多个table name, 并通过 Django ORM
动态创建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初始化新的模型. 这样做更加稳妥一点. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |