django操作mongodb(NOSQL)
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的抉择
- 最直接的方式是使用PyMongo——MongoDB提供的Python Driver。但是用惯了Django的Model层,实在不愿意自己去维护数据库连接,写一大堆CRUD的语句。
- 而django-nonrel,如前所述,未必是一个好的选择。同样的原因,django-mongodb-engine是基于django-nonrel的MongoDB backend实现,也不予考虑。
- 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的方式去思考问题。
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 |
|
在models.py里随便写个模型, 这里要用到mongoengine的一些内容
1 2 3 4 5 |
|
在某个views.py里随便哪里写点逻辑, 添加条数据而已(两种方式都可以填数据)
1 2 3 |
|
然后就可以看看数据输出啦
1 2 |
|
好吧, 如果顺利就应该可以看到console输出的结果, 很给力. 当然在mongo中可以查到如下结果
1 2 |
|
挺好玩的. 最重要的是它支持sessions, 支持User authentication, 还可以使用gridfs做文件存储, 具体可以在这里查到.
Django操作NOSQL(MongoDB)数据库
每一个Django工程师在接触NOSQL数据库的时候,肯定都会思考一个问题:在Django中不能像操作普通的关系型数据库(以下简称RDB)一样,操作NOSQL数据库吗?当然可以,Django工程师几乎不需要什么学习成本,就能使用NOSQL数据库——因为有mongoengine这个模块。
MongoEngine由Python语言写成,提供一个很类似Django ORM的API,本文介绍mongoengine的基本使用,主要是数据结构的定义和内联表单的使用。
Install & Begin
需要安装两个模块,pymongo和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-database.org,NoSQL 数据库是 “下一代数据库,主要具有以下几个要点:非关系型、分布式、开放源码和可水平伸缩”。面向文档的数据库 MongoDB 就是这种类型的数据库。
从一种新的角度来看,Django 1.3 包含了对 SQLite、MySQL、PostgreSQL 和 Oracle 的支持,但是并不包含对 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 所示。
var person1 = {name:"John Doe", age:25}; var person2 = {name:"Jane Doe", age:26, dept: 115}; |
现在,请执行 清单 3 中所示的命令来创建一个新集合。
db.employees.save(person1); db.employees.save(person2); |
由于 MongoDB 具有无模式特性,所以 person1
和 person2
不必具有相同的列类型,甚至不必拥有相同的列编号。并且,MongoDB 本身具有动态特性,所以它会创建 employees 而不是抛出一个错误。您可以通过 find()
方法检索文档。要获取 employees 中的所有文档,可以直接调用 find()
,无需使用任何参数,如 清单 4 所示。
> db.employees.find(); // returns [ { "_id" : { "$oid" : "4e363c4dcc93747e68055fa1" }, "name" : "John Doe", "age" : 25 }, { "_id" : { "$oid" : "4e363c53cc93747e68055fa2" }, "name" : "Jane Doe", "dept" : 115, "age" : 26 } ] |
注意,_id
等效于一个主键。要运行具体的查询,则需要使用键/值对传递另一个对象来指示您所要查询的内容,如清单 5 所示。
> db.employees.find({name: "John Doe"}); // returns [ { "_id" : { "$oid" : "4e363c4dcc93747e68055fa1" }, "name" : "John Doe", "age" : 25 } ] |
要查询年龄大于 25 岁的员工,请执行 清单 6 中的命令。
> db.employees.find({age:{'$gt':25}}); // returns [ { "_id" : { "$oid" : "4e363c53cc93747e68055fa2" }, "name" : "Jane Doe", "dept" : 115, "age" : 26 } ] |
$gt
是一个特殊操作符,表示大于。表 1 列出了其他修饰符。
修饰符 | 描述 |
---|---|
$gt | 大于 |
$lt | 小于 |
$gte | 大于或等于 |
$lte | 小于或等于 |
$in | 检查某个数组是否存在,类似于 'in' SQL 操作符。 |
当然,您也可以使用 update()
方法更新记录。您可以更新整条记录,如 清单 7 所示。
> db.employees.update({ name:"John Doe", // Document to update {name:"John Doe", age:27} // updated document }); |
此外,您还可以使用 $set
操作符仅更新一个值,如 清单 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 命令提示符,以及指南和官方文档。请参阅 参考资料。
有几个从 Python 或 Django 访问 MongoDB 的选项。第一个选项是使用 Python 模块,即 PyMongo。清单 10 是一个简单的 PyMongo 会话,假设您已经安装了 MongoDB,并且已经拥有一个在端口上运行的实例。
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 运行一个查询。
for e in employees.find({"name":"John Doe"}): print e |
您从 Python 调用 MongoDB 的另一个选项是 MongoEngine,如果您使用过 Django 的内置 ORM,那么您对此应该感到非常熟悉。MongoEngine 是一个文档到对象的映射器,从概念上说,它与映射到 ORM 的映射器类似。清单 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 视图拥有三个方法:index
、update
和 delete
。
层叠样式表 (CSS) 定义被引入一个单独的静态文件。相关内容我不想在此处赘述,您可以随意浏览 下载 部分中包含的源代码。
假设已安装好所需的所有工具,并且这些组件都能良好运行,那么请创建一个新的 Django 项目和必要的组件,如清单 13 所示。
$ 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 href="{{STATIC_URL}}blog.css" 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 href="{{STATIC_URL}}blog.css" 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 href="{{STATIC_URL}}blog.css" 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 发送一个请求来完成的。
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 中所示的代码。
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) |
数据库名称是源自设置文件,用于分隔关注点。每个博客帖子都包含三个必要的字段:title
、content
和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 |
最后,您可以创建自己的视图。在这里,您拥有三个视图方法:index
、update
和 delete
。要执行想要执行的操作,则必须向特定 URL 发送一个请求。例如,要更新一个文档,则必须向 localhost:8000/update 发送一个请求。执行一个 http 'GET' 请求不会执行保存、更新等操作。新博客帖子是从索引视图插入的。清单 18 显示了索引、更新和删除视图的实现。
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
语句。
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 操作。虽然这只是第一步,但是希望您现在能够了解如何将此设置应用到您自己的项目中。