Overview
在本指南中,您可以学习如何修改 Djongo项目以使用 Django MongoDB后端。Djongo 是一个第三方库,可将 SQL 查询转换为 MongoDB 查询语言 (MQL) 查询,从而允许您将 MongoDB 用作 Django 4.0 及更早版本的 Django 后端。不过,Django MongoDB 后端是官方支持的集成,可提供更全面的 Django 支持、扩展对 MongoDB 功能的访问权限以及与较新 Django 版本的兼容性。
本指南介绍如何通过更新以下应用程序组件将 Djongo应用程序迁移到 Django MongoDB后端:
数据库设置
要使用 Django MongoDB后端而不是 Djongo 连接到MongoDB ,请修改应用程序的 settings.py文件中的 DATABASES 设置。将此设置的嵌套 ENGINE 键的值从 "djongo" 更新为 "django_mongodb_backend"。然后,在嵌套的 HOST 键而不是 CLIENT 键中指定连接字符串。
提示
要学习;了解有关 DATABASES 设置的更多信息,请参阅 配置数据库连接指南。
例子
以下示例展示了如何修改 DATABASES 设置以使用 Django MongoDB 后端。选择Djongo标签页以查看初始设置配置,然后选择Django MongoDB Backend标签页以查看更新后的设置:
DATABASES = { 'default': { 'ENGINE': 'djongo', 'CLIENT': { 'host': 'mongodb+srv://cluster0.example.mongodb.net', }, 'NAME': 'my_database' } }
DATABASES = { 'default': { 'ENGINE': 'django_mongodb_backend', 'HOST': 'mongodb+srv://cluster0.example.mongodb.net', 'NAME': 'my_database' }, }
模型定义
要更新模型以使用 Django MongoDB 后端,请对模型定义进行以下更改:
从
django.db(而不是djongo)导入models模块。删除显式
ObjectIdField定义,因为 Django MongoDB 后端会自动创建类型为ObjectIdField的_id字段。修改MongoDB特定数组和嵌入式字段的语法。
重要
字段类型
Djongo 和 Django MongoDB后端可能以相同的格式存储Django字段。但是,由于集成的字段转换器存在差异,您可能会遇到不兼容问题。如果您遇到任何问题,可以使用此页面右侧的 Rate this page标签页提交反馈。
提示
要学习更多 Django MongoDB 后端模型,请参阅 创建模型 指南。
单一模型示例
以下示例展示了如何更新名为 Recipe 的模型类以与 Django MongoDB后端兼容。选择Djongo标签页以查看初始模型,然后选择Django MongoDB Backend标签页以查看更新后的模型:
from djongo import models class Tag(models.Model): data = models.CharField(max_length=100) class Meta: abstract = True class Recipe(models.Model): _id = models.ObjectIdField() title = models.CharField(max_length=100) cuisine = models.CharField(max_length=100) cook_time = models.IntegerField(default=0) tags = models.ArrayField(model_container=Tag)
from django.db import models from django_mongodb_backend.fields import ArrayField class Recipe(models.Model): title = models.CharField(max_length=100) cuisine = models.CharField(max_length=100) cook_time = models.IntegerField(default=0) tags = ArrayField( models.CharField(max_length=100), size=4, null=True, blank=True)
要创建存储上述字段的 Recipe对象,请使用以下代码:
Recipe.objects.create( title="Tiramisu", cuisine="Italian", cook_time=20, tags=[ {"data": "dessert"}, {"data": "classic"}, {"data": "espresso"}, {"data": "chocolate"} ] )
Recipe.objects.create( title="Tiramisu", cuisine="Italian", cook_time=20, tags=["dessert", "classic", "espresso", "chocolate"] )
嵌入式模型示例
使用 Djongo 时,可以使用 EmbeddedField 来表示嵌入式MongoDB文档。要定义存储多个嵌入式文档的字段,可以使用 ArrayField。
Django MongoDB后端提供以下表示嵌入式文档的字段:
EmbeddedModelField:存储嵌套模型EmbeddedModelArrayField:存储一个嵌套模型的数组
提示
模型多态性
您不能使用 Djongo 字段来存储包含多种模型类型的数组。但是,Django MongoDB后端提供了 PolymorphicEmbeddedModelField 和 PolymorphicEmbeddedModelArrayField 字段来支持多态性。要学习;了解更多信息,请参阅创建模型指南中的使用高级字段。
以下示例展示如何更新定义 Recipe 模型的 models.py文件,其中包含以下嵌入式模型字段:
nutrition:存储一个表示营养信息的嵌入式Nutrition模型reviews:存储多个表示单个食谱查看的嵌入式Review模型
选择 Djongo标签页以查看初始模型,然后选择 Django MongoDB Backend标签页以查看更新后的模型:
from djongo import models class Nutrition(models.Model): calories = models.IntegerField(default=0) carb_grams = models.IntegerField(default=0) protein_grams = models.IntegerField(default=0) class Meta: abstract = True class Review(models.Model): author = models.CharField(max_length=100) rating = models.IntegerField(default=0) class Meta: abstract = True class Recipe(models.Model): _id = models.ObjectIdField() title = models.CharField(max_length=100) cuisine = models.CharField(max_length=100) cook_time = models.IntegerField(default=0) nutrition = models.EmbeddedField(model_container=Nutrition) reviews = models.ArrayField(model_container=Review)
from django.db import models from django_mongodb_backend.models import EmbeddedModel from django_mongodb_backend.fields import EmbeddedModelField, EmbeddedModelArrayField class Nutrition(EmbeddedModel): calories = models.IntegerField(default=0) carb_grams = models.IntegerField(default=0) protein_grams = models.IntegerField(default=0) class Review(EmbeddedModel): author = models.CharField(max_length=100) rating = models.IntegerField(default=0) class Recipe(models.Model): title = models.CharField(max_length=100) cuisine = models.CharField(max_length=100) cook_time = models.IntegerField(default=0) nutrition = EmbeddedModelField(Nutrition, null=True, blank=True) reviews = EmbeddedModelArrayField(Review, null=True, blank=True)
索引
要更新Djongo应用中的索引以实现 Django MongoDB后端兼容性,您必须使用 Django MongoDB后端提供的索引类。
Djongo 提供单独的类来表示每个 MongoDB 索引,包括单字段索引、复合索引、多键索引等。
Django MongoDB后端提供了以下三个类来表示所有索引类型:
Indexclass:Django 的索引类,代表所有非搜索索引类型SearchIndex类:用于表示 MongoDB 搜索索引的 Django MongoDB 后端特定类VectorSearchIndexclass:特定于 Django MongoDB 后端的类,用于表示 MongoDB Vector Search 搜索索引
提示
要学习有关如何使用 Django MongoDB 后端创建索引的更多信息,请参阅 创建索引 指南。
例子
以下示例展示了如何更新Recipe 模型上的复合索引。Django MongoDB后端实现还添加了MongoDB搜索索引,而 Djongo 不支持该索引。选择Djongo标签页以查看初始索引,然后选择Django MongoDB Backend标签页以查看更新后的索引:
from djongo import models from djongo.models.indexes import CompoundIndex class Recipe(models.Model): _id = models.ObjectIdField() title = models.CharField(max_length=100) cuisine = models.CharField(max_length=100) cook_time = models.IntegerField(default=0) class Meta: indexes = [ CompoundIndex(fields=["title", "cook_time"]) ]
from django.db import models from django_mongodb_backend.indexes import SearchIndex class Recipe(models.Model): title = models.CharField(max_length=100) cuisine = models.CharField(max_length=100) cook_time = models.IntegerField(default=0) class Meta: indexes = [ models.Index(fields=["title", "cook_time"]), SearchIndex(fields=["cuisine"], name="cuisine_search_idx") ]
查询
您可以使用 Django 的 QuerySet API 查询 Djongo 和 Django MongoDB 后端模型。但是,嵌入式模型查询的语法有所不同。
Djongo 将嵌入式模型视为 Python 字典,您必须使用 Python 字典语法来访问或修改其字段。MongoDB MongoDB后端将嵌入式模型视为 Django 模型,因此您可以使用与所有其他模型相同的语法与字段进行交互。
重要
性能回归
Djongo 和 Django MongoDB后端查询生成不同的根本的MQL查询,这可能会对性能产生影响。从 Djongo 迁移到 Django MongoDB 后端时,我们建议您监控性能变化以识别潜在的回归,并在发现任何问题时文件 JIRA 工单。
提示
要进一步学习如何使用 Django MongoDB 后端来查询模型,请参阅 指定查询 指南。
例子
以下示例展示了对 Recipe 模型及其 nutrition 嵌入式模型字段(在嵌入式模型示例部分中定义)进行定义的MongoDB后端查询和 Djongo 查询之间的差异。该代码查询 Nutrition 嵌入式模型的 calories字段。选择 Djongo标签页以查看初始查询,然后选择 Django MongoDB Backend标签页以查看更新后的查询:
Recipe.objects.filter(nutrition__lt={'calories': 500})
Recipe.objects.filter(nutrition__calories__lt=500)
事务
Djongo 和 Django MongoDB后端都支持 Django 的原子事务API功能。但是,它们都提供了自定义API来实现此功能。您可以通过修改代码的 import声明来更新事务以实现 Django MongoDB后端兼容性。
提示
要学习有关如何使用 Django MongoDB 后端执行事务的更多信息,请参阅 事务和会话 指南。
例子
以下示例展示了如何更新代码以导入 Django MongoDB后端的事务 API。选择 Djongo标签页以查看初始声明,然后选择 Django MongoDB Backend标签页以查看更新后的声明:
from djongo import transaction
from django_mongodb_backend import transaction
迁移
默认下,Djongo 不支持数据库迁移,也不实施模式验证。如果您在 settings.py文件中将 ENFORCE_SCHEMA设立为 True,则当检索到的文档缺少字段值时,Djongo 会实施 MigrationErrors。
Django MongoDB后端支持数据库迁移,但有一些限制。要学习;了解有关这些限制的更多信息,请参阅 功能兼容性指南中的迁移支持。
Django MongoDB后端不实施模式验证。因此,更新模型字段而不运行迁移来更新数据库模式不会生成错误。
更多信息
要学习如何设立使用 Django MongoDB 后端的新应用程序,请参阅入门教程。
要了解有关使用 Django MongoDB 后端运行数据库操作的更多信息,请参阅CRUD 操作指南。
要学习有关创建 Django MongoDB 后端模型的更多信息,请参阅 创建模型 指南。