django操作mongodb(NOSQL)

作者: 陳聽溪
发布时间:2015-06-24 11:12:15

http://www.cnblogs.com/holbrook/archive/2012/03/11/2390715.html

  

bala bala NoSQL & MongoDB

目前NoSQL还没有一个标准的定义,最常见的解释是"non-relational",也有很多人解释为“Not Only SQL”。NoSQL通常意味着非关系型、分布式的数据存储,具备大数据量下的高性能,横向扩展能力,以及灵活的数据模型。也许,还意味着开源。

MongoDB是一种以文档形式存储的NoSQL。其主要的特性

API: BSON
Protocol: lots of langs
Query Method: dynamic object-based language & MapReduce
Replication: Master Slave & Auto-Sharding
Written in: C++
Concurrency: Update in Place
Misc: Indexing, GridFS Links

Django对NoSQL的支持

是的,Django将原生支持NoSQL,但是不是现在。

你可能听说过django-nonrel 。即Django none relationship,非关系型的Django。django-nonrel提供了一层adapter,配合特定的backend,可以连接各种NoSQL。比如连接MongoDB的django-mongodb-engine。但是,django-nonrel 的实现是在内存中模拟SQL数据库操作,这种思路没有得到Django核心的支持,所以只能是一个外部版本。

query-refactor是GSoC(Google Summer of Code)的Django项目之一,已经进入Django的官方分支。query-refactor的作者Alex早已公布了query-refactor的“最终状态但是,由于该分支的完成时间与Django1.3的发布时间过于接近,所以没有赶上,在Django1.4的新特性清单docs.djangoproject.com—1.4中也没有找query-refactor的身影。如果有消息灵通人士不妨透露一下。

注:Alex并不是无名小卒,我们知道Django在1.2之前是不支持多数据库的,正是由于Alex的努力,我们才能享用Django的多数据库特性。

Django + MongoDB的抉择

  1. 最直接的方式是使用PyMongo——MongoDB提供的Python Driver。但是用惯了Django的Model层,实在不愿意自己去维护数据库连接,写一大堆CRUD的语句。
  2. 而django-nonrel,如前所述,未必是一个好的选择。同样的原因,django-mongodb-engine是基于django-nonrel的MongoDB backend实现,也不予考虑。
  3. MongoEngine,在Django官方的支持出来之前,我认为这是最好的选择。因为MongoEngine可以提供与Django Model(ORM)非常类似的体验,可以快速上手。看一下官网首页的例子:
    复制代码
    from mongoengine import *                           # To define a schema for a 
    # document, we create a
    class Metadata(EmbeddedDocument): # class that inherits from
    tags = ListField(StringField()) # Document.
    revisions = ListField(IntField()) #
    # Fields are specified by
    class WikiPage(Document): # adding field objects as
    title = StringField(required=True) # class attributes to the
    text = StringField() # document class.
    metadata = EmbeddedDocumentField(Metadata) #
    # Querying is achieved by
    >>> page.title = “Hello, World!” # calling the objects
    >>> for page in WikiPage.objects: # attribute on a document
    >>> print page.title # class.
    复制代码

Django+MongoEngine

首先安装MongoEngine(依赖pymongo)。之后在python shell中实验一下:

复制代码
from mongoengine import *

connect('employeeDB')
class Employee(Document):
name = StringField(max_length=50)
age = IntField(required=False)

john = Employee(name="John Doe", age=25)
john.save()

jane = Employee(name="Jane Doe", age=27)
jane.save()

for e in Employee.objects.all():
print e["id"], e["name"], e["age"]
复制代码

在Django中使用也很容易,只需在models.py(如果你十分介意,也可以单独放在docs.py中)这样写:

复制代码
from mongoengine import *
from mysite.settings import DBNAME

connect(DBNAME)
class Employee(Document):
name = StringField(max_length=50)
age = IntField(required=False)
复制代码

其中,DBNAME在settings.py中指定。

然后,在视图中就可以使用“文档模型“了。

其他

1.Mongo Engine的Field类型与Django ORM的Field类型有所不同,下面是一个简单的对比:

 
MongoEngine Django
StringField CharField
URLField URLField
EmailField EmailField
IntField IntegerField
FloatField FloatField
DecimalField DecimalField
BooleanField BooleanField
DateTimeField DateTimeField
EmbeddedDocumentField --
DictField --
ListField --
SortedListField --
BinaryField --
ObjectIdField --
FileField FileField

2.尽管看起来像是ORM,但MongoDB绝对不是RDB。我想MongoEngine这样的设计是为了方便上手,但是使用的时候,一定要按照NoSQL的方式去思考问题。

 

本人已在github上用Jekyll建立了新的博客:http://thinkinside.tk/,本站文章会陆续迁移过去


 
 
标签: djangopython

 

 

                     http://artori.us/use-mongodb-with-django/

优雅的在django框架里使用mongodb

在我们这里关于ruby和python的争论永远没有停息, 比赛之前也无意间让我发现了很多东西. 这次发现了一个django中使用mongodb的好东西, 叫做mongoengine, 不知道是不是我火星了, 因为从github上看这个项目最早从09年11月就开始了.

在github下载到源码, 有setup.py, 先build再install, 然后… 开搞!

先很简单的创建一个django的工程(具体不说django), 然后弄个小app或者随便哪里写个view就好了. 然后我用了几步就确定它可以正常使用了.

首先修改settings.py, 原来DATABASES完全不用去管它了, 全部设为空串就好, 然后在文件里加上下面的内容

1  2  
from mongoengine import connect  connect('DB_NAME')  

在models.py里随便写个模型, 这里要用到mongoengine的一些内容

1  2  3  4  5  
from mongoengine import Document  class TestModel(Document):      test_key = StringField(required=True)      test_value = StringField(max_length=50)  

在某个views.py里随便哪里写点逻辑, 添加条数据而已(两种方式都可以填数据)

1  2  3  
entry = TestModel(test_key='arthur')  entry.test_value = 'Wang'  entry.save()  

然后就可以看看数据输出啦

1  2  
for entry in TestModel.objects:      print entry.test_key  

好吧, 如果顺利就应该可以看到console输出的结果, 很给力. 当然在mongo中可以查到如下结果

1  2  
db.testmodel.find()  { "_id" : ObjectId("4d34267f7ecfdb3b7c000000"), "test_key" : "arthur", "test_value" : "Wang", "_types" : [ "TestModel" ], "_cls" : "TestModel" }  

挺好玩的. 最重要的是它支持sessions, 支持User authentication, 还可以使用gridfs做文件存储, 具体可以在这里查到.

 

                         http://dmyz.org/archives/251

Django操作NOSQL(MongoDB)数据库

每一个Django工程师在接触Nosql数据库的时候,肯定都会思考一个问题:在Django中不能像操作普通的关系型数据库(以下简称RDB)一样,操作NOSQL数据库吗?当然可以,Django工程师几乎不需要什么学习成本,就能使用NOSQL数据库——因为有mongoengine这个模块。

MongoEngine由Python语言写成,提供一个很类似Django ORM的API,本文介绍mongoengine的基本使用,主要是数据结构的定义和内联表单的使用。

Install & Begin

需要安装两个模块,pymongo和mongoengine

pip install -U mongoengine
pip install pymongo

现在我们以最快的方式利用Django对MongoDB进行操作,请在电脑旁放置一个秒表,理论上完成这些操作的时间不会超过3分钟:

新建一个应用,其中新建一个docs.py文件,代码如下:

1  2  3  4  5  6  7  
from mongoengine import *  connect('test')     class User(Document):      username = StringField(required=True)      website = URLField()      tags = ListField(StringField(max_length=16))

然后编辑views.py文件:

1  2  3  4  5  6  7  8  9  10  11  12  
from django.http import HttpResponse  from . import docs     def index(request):      user1 = docs.User(          username='Perchouli',          website='http://dmyz.org',           tags = ['Web','Django','JS']      )      user1.save()      Oid = user1.id      return HttpResponse(Oid)

最后,把视图加到URL中,访问这个视图可以看到返回的ObjectID,我们已经实现了对NOSQL数据库的写入和查找了。是不是和Django ORM几乎一样呢?

Philosophy

回头说说代码。docs.py中的语法很类似models.py,但两者的用途完全不同。mongoengine是定义一个scheme,这些定义不会写入到数据库中。

在User中使用了三种Field,MongoDB是使用JSON格式存储数据,所以写入的值也可以是对象/数组/字典,mongoengine会自动将Python数据格式转换成JS数据格式,但必须按照之前的定义的Field类型来传值。比如上例中的tags被定义为数组(ListField),数组中的每个元素是字符(StringField),mongoengine只接受同样类型的数据格式。

EmbeddedField

RDB对数据的组织是建立在“关系”之上的,比如我们要存储某个用户的Profile,它与用户ID是多对一的关系,在RDB中,通常要新建一张名为Profile的表,其中包含UserID和Profile,每一条数据对应一个Profile的记录,这种方式多少显得有些笨拙。NOSQL的出现解决了这类问题,在NOSQL数据库中使用内联的方式,直接把Profile存在User下,调用User时就可以获得Profile的数据了。

修改上例中的docs.py,增加Profile:

1  2  3  4  5  6  7  8  9  10  11  12  13  
from mongoengine import *  connect('test')  #先定义名为Profile的EmbeddedDocument  class Profile(EmbeddedDocument):      gender = StringField()      location = StringField()     class User(Document):      username = StringField(required=True)      website = URLField()      tags = ListField(StringField(max_length=16))      #添加到User      profile = EmbeddedDocumentField(Profile)

再修改views.py,为了显示区别这里输出一个JSON格式的字符串:

1  2  3  4  5  6  7  8  9  10  11  12  13  14  
from django.http import HttpResponse  from . import docs     def index(request):      profile1 = docs.Profile(gender='male', location='Beijing')      user1 = docs.User(          username='Perchouli',          website='http://dmyz.org',           tags = ['Web','Django','JS'],          profile = profile1      )      user1.save()      user1_json = str(user1.to_mongo())      return HttpResponse(user1_json)

怎么读取profile中的gender和location?我不说你可能也想到了:user1.profile.gender。其他的操作也一样,都是用for来遍历数据,查找、删除也是类似的语法。

Afterword

mongoengine这种类似ORM的写法提供了一个很好的过渡方式,但NOSQL数据库毕竟不是构建于”关系”之上的,很多ORM的经验并不适用。其实操作NOSQL数据库,对它进行增删改查并不复杂,真正头疼的是数据的建模,具体的业务逻辑,怎样设计才能最大限度的发挥NOSQL数据库的用途等等一些列问题。mongoengine降低了Django工程师使用NOSQL数据库的门槛,相信只要有更多的人参与其中,这类经验会逐步丰富和完善的。

       

 

 

 

http://www.ibm.com/developerworks/cn/opensource/os-django-mongo/

Django 是在一个极为出色的模块化样式中得到应用的;替换一个基于 Django 的 Web 应用程序的不同组件非常简单。由于 NoSQL 目前较为常见,您可能想要尝试运行一个具有不同后端而非具有标准关系数据库(如 MySQL®)的应用程序。在本文中,您将初体验 MongoDB,包括如何使用 PyMongo 或 MongoEngine 在您的 Python 项目中调用它。接着,您将使用 Django 和 MongoEngine 创建一个可执行创建、读取、更新、删除 (CRUD) 操作的简单博客。

关于 NoSQL 数据库

根据 nosql-database.org,NoSQL 数据库是 “下一代数据库,主要具有以下几个要点:非关系型、分布式、开放源码和可水平伸缩”。面向文档的数据库 MongoDB 就是这种类型的数据库。

从一种新的角度来看,Django 1.3 包含了对 SQLite、MySQL、PostgreSQL 和 Oracle 的支持,但是并不包含对 MongoDB 的支持。不过,要添加对 MongoDB 的支持非常容易,但要以失去自动管理面板为代价。因此,您必须根据您的需要进行权衡。

 

回页首

MongoDB 简介

MongoDB 可以充当 JavaScript 解释器,因此数据库操作是通过 JavaScript 命令完成的。在您的机器上本地安装 MongoDB 后(参见 参考资料),可以尝试使用 清单 1 中列出的一些命令。


清单 1. 您可以尝试对 MongoDB 使用的样例 JavaScript 命令

				  var x = "0";  x === 0;  typeof({});   

 

您不必成为一名 JavaScript 专家之后才开始使用 MongoDB;这里提供几个有用的概念:

  • 您可以使用对象字面量语法 (object literal syntax) 创建对象,换句话说,会使用两个花括号(如 var myCollection = {};)。
  • 您可以使用方括号([])来创建数组。
  • 除了数字、布尔值、null 和未定义值以外,JavaScript 中的其他所有值都是一个对象。

如果您想要了解关于 JavaScript 其他特性的更多信息,比如原型的面向对象的编程 (OOP)、范围规则,及其函数式编程特性,请参阅 参考资料

MongoDB 是一种无模式数据库,与关系型数据库完全相反。无模式数据库没有使用表格,而是使用由文档组成的集合。这些文档是使用对象字面量语法创建的,如 清单 2 所示。


清单 2. 文档创建示例

				  var person1 = {name:"John Doe", age:25};  var person2 = {name:"Jane Doe", age:26, dept: 115};  

 

现在,请执行 清单 3 中所示的命令来创建一个新集合。


清单 3. 创建集合

				  db.employees.save(person1);  db.employees.save(person2);  

 

由于 MongoDB 具有无模式特性,所以 person1 和 person2 不必具有相同的列类型,甚至不必拥有相同的列编号。并且,MongoDB 本身具有动态特性,所以它会创建 employees 而不是抛出一个错误。您可以通过 find() 方法检索文档。要获取 employees 中的所有文档,可以直接调用 find(),无需使用任何参数,如 清单 4 所示。


清单 4. 一个简单的 MongoDB 查询

				  > db.employees.find();  // returns  [     {   "_id" : {   "$oid" : "4e363c4dcc93747e68055fa1"   },             "name" : "John Doe",   "age" : 25   },    {   "_id" : {   "$oid" : "4e363c53cc93747e68055fa2"   },             "name" : "Jane Doe",   "dept" : 115,   "age" : 26   }  ]  

 

注意,_id 等效于一个主键。要运行具体的查询,则需要使用键/值对传递另一个对象来指示您所要查询的内容,如清单 5 所示。


清单 5. 通过一个搜索参数进行查询

				    > db.employees.find({name: "John Doe"});  // returns  [     {   "_id" : {   "$oid" : "4e363c4dcc93747e68055fa1"   },       "name" : "John Doe",   "age" : 25   }  ]  

 

要查询年龄大于 25 岁的员工,请执行 清单 6 中的命令。


清单 6. 查询年龄大于 25 岁的员工

				  > db.employees.find({age:{'$gt':25}});  // returns  [     {   "_id" : {   "$oid" : "4e363c53cc93747e68055fa2"   },       "name" : "Jane Doe",   "dept" : 115,   "age" : 26   }  ]  

 

$gt 是一个特殊操作符,表示大于。表 1 列出了其他修饰符。


表 1. 可以对 MongoDB 使用的修饰符

修饰符描述
$gt 大于
$lt 小于
$gte 大于或等于
$lte 小于或等于
$in 检查某个数组是否存在,类似于 'in' SQL 操作符。

 

当然,您也可以使用 update() 方法更新记录。您可以更新整条记录,如 清单 7 所示。


清单 7. 更新整条记录

				  > db.employees.update({      name:"John Doe",  // Document to update      {name:"John Doe", age:27} // updated document    });  

 

此外,您还可以使用 $set 操作符仅更新一个值,如 清单 8 所示。


清单 8. 仅更新记录中的一个值

				  > db.employees.update({name:"John Doe",        { '$set': {age:27} }    });   

 

要清空集合,可以调用 remove() 方法,无需使用任何参数。例如,如果您想要从 employees 集合中移除 John Doe,那么您可以执行 清单 9 所示的操作。


清单 9. 从 employees 集合中移除 John Doe

				  > db.employees.remove({"name":"John Doe"});  > db.employees.find();  // returns  [     {   "_id" : {   "$oid" : "4e363c53cc93747e68055fa2"   },   "name" : "Jane Doe",           "dept" : 115,   "age" : 26   }  ]  

 

此内容对于刚开始使用 MongoDB 的您来说已经足够了。当然,您可以继续浏览官方网站,该网站提供了简洁的、基于 Web 的交互式 mongodb 命令提示符,以及指南和官方文档。请参阅 参考资料

 

回页首

将 Django 与 MongoDB 集成

有几个从 Python 或 Django 访问 MongoDB 的选项。第一个选项是使用 Python 模块,即 PyMongo。清单 10 是一个简单的 PyMongo 会话,假设您已经安装了 MongoDB,并且已经拥有一个在端口上运行的实例。


清单 10. 样例 PyMongo 会话

				    from pymongo import Connection    databaseName = "sample_database"  connection = Connection()    db = connection[databaseName]  employees = db['employees']    person1 = { "name" : "John Doe",              "age" : 25, "dept": 101, "languages":["English","German","Japanese"] }    person2 = { "name" : "Jane Doe",              "age" : 27, "languages":["English","Spanish","French"] }    print "clearing"  employees.remove()    print "saving"  employees.save(person1)  employees.save(person2)    print "searching"  for e in employees.find():      print e["name"] + " " + unicode(e["languages"])  

 

PyMongo 允许您同时运行多个数据库。要定义一个连接,只需将数据库名字传递给连接实例。在本例中,Python 词典代替了 JavaScript 对象字面量来创建新文档定义,而 Python 列表代替了 JavaScript 数组。find 方法会返回一个您可以进行迭代的数据库游标对象。

语法的简易性使 MongoDB 命令行与包含 PyMongo 的运行命令之间的切换变得容易。例如,清单 11 展示了如何使用 PyMongo 运行一个查询。


清单 11. 使用 PyMongo 运行一个查询

				  for e in employees.find({"name":"John Doe"}):      print e  

 

您从 Python 调用 MongoDB 的另一个选项是 MongoEngine,如果您使用过 Django 的内置 ORM,那么您对此应该感到非常熟悉。MongoEngine 是一个文档到对象的映射器,从概念上说,它与映射到 ORM 的映射器类似。清单 12 显示了一个使用 MongoEngine 的示例会话。


清单 12. MongoEngine 示例会话

				    from mongoengine import *    connect('employeeDB')    class Employee(Document):      name = StringField(max_length=50)      age = IntField(required=False)    john = Employee(name="John Doe", age=25)  john.save()    jane = Employee(name="Jane Doe", age=27)  jane.save()    for e in Employee.objects.all():      print e["id"], e["name"], e["age"]  

 

Employee 对象继承自 mongoengine.Document。在本示例中,使用了两种字段类型:StringField 和 IntField。与 Django 的 ORM 相似,要通过查询获得集合中的所有文档,请调用 Employee.objects.all()。请注意,要访问惟一的对象 ID,请使用 "id" 而非 "_id"

 

回页首

一个样例博客

现在要创建一个名为 Blongo 的简单博客。您将使用 Python 1.7、Django 1.3、MongoDB 1.8.2、MongoEngine 0.4 和 Hypertext Markup Language (HTML) 5。如果您想要重现我的精确设置,我习惯使用 Ubuntu Linux 和 FireFox。Blongo 在网页加载后就会显示所输入的所有博客条目,并且允许对任何条目执行更新和删除操作,换句话说,允许进行所有的标准 CRUD 操作。Django 视图拥有三个方法:indexupdate 和 delete

层叠样式表 (CSS) 定义被引入一个单独的静态文件。相关内容我不想在此处赘述,您可以随意浏览 下载 部分中包含的源代码。

假设已安装好所需的所有工具,并且这些组件都能良好运行,那么请创建一个新的 Django 项目和必要的组件,如清单 13 所示。


清单 13. 创建 Django 博客项目的命令

				  $ django-admin.py startproject blongo  $ cd blongo  $ django-admin.py startapp blogapp  $ mkdir templates  $ cd blogapp  $ mkdir static  

 

Django 1.3 的新增内容是一个已包含在 Django 中的贡献型应用程序,可使用它来改进静态文件的处理。通过向任何应用程序目录添加一个静态目录(例如,本例中的 blogapp)并确保 django.contrib.staticfiles 包含在已安装应用程序中,Django 可以查找到诸如 .css 和 .js 的静态文件,而无需使用其他任何方法。清单 14 显示了设置文件的代码行,这些代码行已经进行了相应修改(来自默认的 settings.py 文件),使博客应用程序能够正常运行。


清单 14. 已改变的设置文件代码行(来自默认的 settings.py 文件)

				  # Django settings for blog project.  import os  APP_DIR = os.path.dirname( globals()['__file__'] )    DBNAME = 'blog'    TEMPLATE_DIRS = (      os.path.join( APP_DIR, 'templates' )  )    INSTALLED_APPS = (      'django.contrib.auth',      'django.contrib.contenttypes',      'django.contrib.sessions',      'django.contrib.sites',      'django.contrib.messages',      'django.contrib.staticfiles',      'blog.blogapp',  )    

 

本项目中也有三个模板:index.html、update.html 和 delete.html。清单 15 显示了这三个模板文件的代码。


清单 15. index.html、update.html 和 delete.html 模板文件的代码 

				  <!-- index.html -->  <!DOCTYPE html>  <html>    <head>      <link   rel="stylesheet" type="text/css">    </head>     <body>      <h1>Blongo</h1>      <form method="post" action="http://127.0.0.1:8000/">        {% csrf_token %}        <ul>          <li>            <input type="text" name="title" placeholder="Post Title" required>          </li>          <li>            <textarea name="content" placeholder="Enter Content" rows=5 cols=50 required>            </textarea>          </li>          <li>            <input type="submit" value="Add Post">          </li>        </ul>      </form>  <!-- Cycle through entries -->      {% for post in Posts %}        <h2> {{ post.title }} </h2>        <p>{{ post.last_update }}</p>        <p>{{ post.content }}</p>        <form method="get" action="http://127.0.0.1:8000/update">          <input type="hidden" name="id" value="{{ post.id }}">          <input type="hidden" name="title" value="{{ post.title }}">          <input type="hidden" name="last_update" value="{{ post.last_update }}">          <input type="hidden" name="content" value="{{ post.content }}">          <input type="submit" name="" value="update">        </form>        <form method="get" action="http://127.0.0.1:8000/delete">          <input type="hidden" name="id" value="{{post.id}}">          <input type="submit" value="delete">        </form>      {% endfor %}    </body>  </html>    <!-- update.html -->  <!DOCTYPE html>  <html>    <head>      <link   rel="stylesheet" type="text/css">    </head>     <body>      <h1>Blongo - Update Entry</h1>      <form method="post" action="http://127.0.0.1:8000/update/">        {% csrf_token %}        <ul>          <li><input type="hidden" name="id" value="{{post.id}}"></li>          <li>            <input type="text" name="title" placeholder="Post Title"                value="{{post.title}}" required>            <input type="text" name="last_update"                value="{{post.last_update}}" required>          </li>          <li>            <textarea name="content" placeholder="Enter Content"               rows=5 cols=50 required>              {{post.content}}            </textarea>          </li>          <li>            <input type="submit" value="Save Changes">          </li>        </ul>      </form>    </body>  </html>  <!-- delete.html -->  <!DOCTYPE html>  <html>    <head>      <link   rel="stylesheet" type="text/css">      </head>     <body>      <h1>Blongo - Delete Entry</h1>      <form method="post" action="http://127.0.0.1:8000/delete/">        {% csrf_token %}        <input type="hidden" name="id" value="{{id}}">        <p>Are you sure you want to delete this post?</p>        <input type="submit" value="Delete">      </form>    </body>  </html>  

 

接着,更改 清单 16 中所示代码的 URL 映射,该映射指向索引、更新和删除的视图。您可能想让样例博客创建新的博客条目(在索引中)、更新现有博客帖子,并在想要删除这些帖子的时候删除它们。每个操作都是通过向特定 URL 发送一个请求来完成的。


清单 16. 索引、更新和删除的映射

				  from django.conf.urls.defaults import patterns, include, url    urlpatterns = patterns('',      url(r'^$', 'blog.blogapp.views.index'),      url(r'^update/', 'blog.blogapp.views.update'),      url(r'^delete/', 'blog.blogapp.views.delete'),  )  

 

注意,您 需运行 syncdb Django 命令。要将 MongoDB 集成到您的应用程序中,只需使用 MongoEngine 即可。在 blogapp 目录的 models.py 文件中,添加 清单 17 中所示的代码。


清单 17. 在数据层中包含 MongoEngine

				  from mongoengine import *  from blog.settings import DBNAME    connect(DBNAME)    class Post(Document):      title = StringField(max_length=120, required=True)      content = StringField(max_length=500, required=True)      last_update = DateTimeField(required=True)  

 

数据库名称是源自设置文件,用于分隔关注点。每个博客帖子都包含三个必要的字段:titlecontent 和last_update。如果您将此清单与您通常在 Django 获得的清单进行对比,就会发现它们差别并不大。此清单使用了mongoengine.Document 类,而非从 django.db.models.Model 中继承的类。在这里,我并不打算深入探讨数据类型之间的差别,但您可以随意查看 MongoEngine 文档(参见 参考资料)。

表 2 列出了 MongoEngine 字段类型,并显示了对等的 Django ORM 字段类型(如果存在的话)。


表 2. MongoEngine 字段类型和 Django ORM 对等物

MongoEngine 字段类型Django ORM 对等物
StringField CharField
URLField URLField
EmailField EmailField
IntField IntegerField
FloatField FloatField
DecimalField DecimalField
BooleanField BooleanField
DateTimeField DateTimeField
EmbeddedDocumentField None
DictField None
ListField None
SortedListField None
BinaryField None
ObjectIdField None
FileField FileField

 

最后,您可以创建自己的视图。在这里,您拥有三个视图方法:indexupdate 和 delete。要执行想要执行的操作,则必须向特定 URL 发送一个请求。例如,要更新一个文档,则必须向 localhost:8000/update 发送一个请求。执行一个 http 'GET' 请求不会执行保存、更新等操作。新博客帖子是从索引视图插入的。清单 18 显示了索引、更新和删除视图的实现。


清单 18. Django 视图

				  from django.shortcuts import render_to_response  from django.template import RequestContext  from models import Post  import datetime    def index(request):      if request.method == 'POST':         # save new post         title = request.POST['title']         content = request.POST['content']           post = Post(title=title)         post.last_update = datetime.datetime.now()          post.content = content         post.save()        # Get all posts from DB      posts = Post.objects       return render_to_response('index.html', {'Posts': posts},                                context_instance=RequestContext(request))      def update(request):      id = eval("request." + request.method + "['id']")      post = Post.objects(id=id)[0]            if request.method == 'POST':          # update field values and save to mongo          post.title = request.POST['title']          post.last_update = datetime.datetime.now()           post.content = request.POST['content']          post.save()          template = 'index.html'          params = {'Posts': Post.objects}         elif request.method == 'GET':          template = 'update.html'          params = {'post':post}           return render_to_response(template, params, context_instance=RequestContext(request))                                    def delete(request):      id = eval("request." + request.method + "['id']")        if request.method == 'POST':          post = Post.objects(id=id)[0]          post.delete()           template = 'index.html'          params = {'Posts': Post.objects}       elif request.method == 'GET':          template = 'delete.html'          params = { 'id': id }         return render_to_response(template, params, context_instance=RequestContext(request))  

 

您可能已经注意到用来索引文档 ID 的 eval 语句。使用该语句是为了避免编写 清单 19 中所示的 if 语句。


清单 19. 检索文档 ID 的替代方法

				      if request.method == 'POST':          id = request.POST['id']      elif request.method == 'GET':          id = request.GET['id']  

 

您也可以这样编写代码。以上就是创建并运行一个简单博客需要执行的所有操作。显然,最终产品中还会添加许多组件,比如用户、登录、标签等。

结束语

正如您所看到的,从 Django 调用 MongoDB 真的不是很复杂。在本文中,我简单介绍了一下 MongoDB,并解释了如何访问它,以及如何通过 PyMongo 包装器和 MongoEngine 的 “对象至文档” 映射器,从 Python 操作 MongoDB 的集合和文档。最后,我快速演示了如何使用 Django 执行基础 CRUD 操作。虽然这只是第一步,但是希望您现在能够了解如何将此设置应用到您自己的项目中。

 

 

 

          

                 

来源:http://www.cnblogs.com/taosim/articles/3314717.html

推荐: