1.背景知识

  需要开发一个系统,处理大量EXCEL表格信息,各种类别。表格标题多变,因此使用不需要预先设计数据表结构的MongoDB,即NoSQL。一是字段不固定,二是同名字段可以存储不同的字段类型。

  同时,后端确定使用Django,原因是数据处理这一块,python无敌于天下。

  Django采用MVT模式开发。MODEL是最关键的部分。是ORM的核心。但是ORM主要用于关系型数据库。那么如何解决?

2.大量调研的网上资料

(1)mongoengine

    mongoengine(跟pymongodb类似,但是相比于后者,又能提供模型类的功能,封装一些数据操作,不用单独写一堆crub)

缺点:经反复测试研究,不支持django的原生后台管理功能,因为无法将django的数据迁移到mongodb数据库中因此无法使用原生的后台管理界面,需要定制。

(2)djongo(注意不是django。爹是django,妈是mongodb,交配出来的物种)

       

       与Django支持的其它SQL数据库类型,用于支持Nosql。

       可以将django的数据迁移到mongodb数据库中,也可以使用原生的后台管理界面

(3)Django-nonrel

  django的分支,有时间可以研究一下。

3.目前的问题(用mongodb仿ORM,那么如何随时变动字段?)

  OVM模型的重点就是提前定义类的成员,同时迁移到数据表中,形成相应字段。

对于一个excel表,记录图书信息,比如,书名,出版日期。

我们只需要用下述方式定义一个类,

# 创建图书类
class BookInfo(models.Model):
"""图书模型类"""
# 图书名称,CharField说明是该类属性是一个字符串,max_length指定最大长度
book_title = models.CharField(max_length=20) # 出版日期,DateField说明该类属性是一个日期
book_pub_date = models.DateField() def __str__(self):
"""覆盖对BookInfo实例化对象使用str()的返回值"""
return self.book_title # 返回书名

  作为model放入django中。后面执行如下操作,数据库就可以相应的自动变化了。

有djongo对django和mongodb支持,我们可以将mongodb“仿”为ORM模型,注意,是仿。

def get(request):
# book=BookInfo()
# book.book_title='水浒传'
# book.book_pub_date=date(1960,1,1) # book.save()
# return HttpResponse('helloworld')

  那么如何随时变动字段呢?比如,哪天使用方的excel表格又变动了,增加了一列,比如作者。那么如何将作者这个字段加入呢?同时,不改变原始代码?

4.解决方案(动态模型类)

(1)模型save的局限性

 首先,python支持类成员随时定义,我们直接在模型类对象中,添加一个成员。 
# book.author = '罗贯中'
但是发现模型的save操作,对这个临时增加的成员不处理,无法加入数据库中。
save只处理在原始models.py文件中定义BookInfo的时候定义的固定类成员。
通过调试发现,Django在运行前需要首先对各个models.py进行解析。因此,后续在模型类实例化对象中临时增加成员,是没用的。

(2)我的方式:强制解析新的模型类,支持对字段进行变动,更好时候NoSQL

 通过文件定义的类,具有一些特殊字段。__module__ __qualname和__doc__

   由于Django只处理models.py文件中定义的模型类。所以,

   在程序执行时,动态创建新的模型类,并且修改其成员属性,把其仿真为文件中定义的模型类,然后再用django进行解析,使其能够作为ORM的新model。

   

BookInfo = type('BookInfo', (models.Model,), {"__module__":"booktest.models",'__qualname__':'BookInfo',"__doc__":"注释", "book_title": models.CharField(max_length=20),"book_pub_date" :models.DateField(),"author": models.CharField(max_length=20)})
book=BookInfo()
book.book_title='三国演义xxx'
book.book_pub_date=date(1960,1,1)
book.author='我是杰少啊'
book.save()

 注意两点:第一,由于内存中有原始模型类BookInfo,我们要对其完全覆盖掉。

上面type为什么会触发django重新解析模型类呢?

因为BookInfo继承的model,核心是继承Django的ModelBase类。当执行上述动态类定义过程时,就会触发解析。

通过上述处理,我们就能实现对数据库插入作者字段了。数据库中内容如下:

 

(动态模型类,我的独创)Django的原生ORM框架如何支持MongoDB,同时应对客户使用时随时变动字段的更多相关文章

  1. Django中的ORM框架使用小技巧

      Django中的ORM框架使用小技巧 作者:尹正杰  版权声明:原创作品,谢绝转载!否则将追究法律责任. Django对各个数据提供了很好的支持,包括PostgreSQL,MySQL,SQLite ...

  2. django的模型类管理器-----------数据库操作的封装

    模型实例方法 str():在将对象转换成字符串时会被调用. save():将模型对象保存到数据表中,ORM框架会转换成对应的insert或update语句. delete():将模型对象从数据表中删除 ...

  3. django内置 Contenttypes 框架

    一.什么是Django ContentTypes? 1.Django 包含一个ContentTypes 应用,它可以追踪安装在你的Django 项目里的所有应用,并提供一个高层次的.通用的接口用于与你 ...

  4. Django模型类Meta元数据详解

    转自:https://my.oschina.net/liuyuantao/blog/751337 简介 使用内部的class Meta 定义模型的元数据,例如: from django.db impo ...

  5. django的models模型类的常用数据类型和选项

    django框架的models模块ORM框架,能够让我们通过编写类的方式,帮助我们自动生成数据库表. 生成的数据库表名为 应用模块名称_类名 数据库表中字段名 如果我们没有在参数中指定,就是我们写的类 ...

  6. Django商城项目笔记No.3用户部分-用户模型类

    Django商城项目笔记No.3用户部分-用户模型类 Django提供了认证系统,文档资料https://yiyibooks.cn/xx/Django_1.11.6/topics/auth/index ...

  7. django定义模型类-14

    目录 1. 定义 字段类型 约束类型 django的模型类定义在应用下的 models.py 文件中. 模型类继承自 django.db.models 包下的 Model 类. 新创建应用 book ...

  8. django定义模型类

    模型类被定义在应用文件夹下的model.py中 模型类必须继承Django的models.Model类 属性名不能用连续的两条下划线__ 主键:primary key,简写 pk 不需要主动定义,dj ...

  9. 7.Django模型类的定义和管理

    Django的模型类是给ORM层服务的 1.每个数据模型都是django.db.models.Model的子类. 2.它的父类Model包含了所有必要的和数据库交互的方法,并提供了定义数据库字段的语法 ...

随机推荐

  1. 分析vue脚手架

    执行流程: 执行npm run serve.找到了main.js文件,之后引入Vue.App等等.后来找到App组件,发现里面用到了组件School,于是执行School组件,最终汇总到App组件.通 ...

  2. win server 2012下安装IIS 8后配置ASP网站的注意事项

    1,安装IIS时,如果你用不到asp.net 在web下的应用程序开发只需要勾选ASP这一项就可以. 2,IIS测试成功后,需要在你设定的主目录添加权限,找到你的主目录-属性-安全-编辑,添加Ever ...

  3. 09 Java的方法 方法的重载 命令行传参

    3.方法的重载 重载就是在一个类中,有相同的函数名称,单形参不同的函数. 方法的重载的规则: 方法名称必须相同. 参数列表必须不同(个数不同.或类型不同.参数排序顺序不同等). 方法的返回类型可以相同 ...

  4. 08 Java的方法 方法的定义

    2.方法的定义 Java的方法类似于其他语言的函数,是一段用来完成特定功能的代码片段,一般情况下,定义一个方法包含以下语法: **方法包含一个方法头和一个方法体.**下面是一个方法的所有部分: 修饰符 ...

  5. CF375D题解

    昨天教练布置的莫队作业,然后一看我老早就用 DSU on tree 切了,来补题解( 题意 静态树询问子树中,同一种元素的数量不小于 \(k\) 的元素有多少种. 莫队做法 容易观察到子树在 \(\r ...

  6. vue/cli项目添加外部js文件的一个方法

    有一个util.js文件,内容如下 function Util () { ... } export default new Util() 可以在main.js里面通过import引入js import ...

  7. 一致性 Hash 在负载均衡中的应用

    介 一致性Hash是一种特殊的Hash算法,由于其均衡性.持久性的映射特点,被广泛的应用于负载均衡领域,如nginx和memcached都采用了一致性Hash来作为集群负载均衡的方案.本文将介绍一致性 ...

  8. chili

    靶机准备 首先将靶机ova文件导入 网络模式改为NAT 扫描ip netdiscover -r 192.168.164.0/24 kali:192.168.164.137 渗透测试 扫描端口 nmap ...

  9. [FromBody]List<string> 用PostMan如何请求

    在MVC项目,写了一个API方法,如下: /// <summary>/// 测试/// </summary>/// <param name="idList&qu ...

  10. bzoj5417/luoguP4770 [NOI2018]你的名字(后缀自动机+线段树合并)

    bzoj5417/luoguP4770 [NOI2018]你的名字(后缀自动机+线段树合并) bzoj Luogu 给出一个字符串 $ S $ 及 $ q $ 次询问,每次询问一个字符串 $ T $ ...