Overview
在本指南中,您可以学习;了解如何修改 Djongo项目以使用 Django MongoDB后端。 Djongo 是一个第三方库,可将SQL查询转换为MongoDB查询语言 (MQL) 查询,从而允许您将MongoDB用作 Django 4.0 及更早版本的 Django后端。不过,MongoDB MongoDB后端是官方支持的集成,可提供更全面的 Django支持、扩展对MongoDB功能的访问权限以及与较新 Django 版本的兼容性。
本指南介绍如何通过更新以下应用程序组件将 Djongo应用程序迁移到 Django MongoDB后端:
数据库设置
要使用 Django MongoDB后端而不是 Djongo 连接到MongoDB ,请修改应用程序的 settings.py文件中的 DATABASES 设置。将此设置的嵌套 ENGINE 键的值从 "djongo" 更新为 "django_mongodb_backend"。然后,在嵌套的 HOST 键而不是 CLIENT 键中指定连接字符串。
例子
以下示例展示了如何修改 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标签页页提交反馈。
单一模型示例
以下示例展示了如何更新名为 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:存储嵌套模型的大量
提示
模型多态性
以下示例展示如何更新定义 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 的索引类,代表所有非 Search索引类型SearchIndex类:用于表示MongoDB搜索索引的特定于 Django MongoDB后端的类VectorSearchIndexclass:特定于 Django MongoDB后端的类,用于表示MongoDB Vector Search 索引
例子
以下示例展示了如何更新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 的 API查询Djongo 和 DjangoQuerySet MongoDB后端模型。但是,嵌入式模型查询的语法有所不同。
Djongo 将嵌入式模型视为Python字典,您必须使用Python字典语法来访问权限或修改其字段。 MongoDB MongoDB后端将嵌入式模型视为 Django 模型,因此您可以使用与所有其他模型相同的语法与字段进行交互。
重要
性能回归
Djongo 和 Django MongoDB后端查询生成不同的根本的MQL查询,这可能会对性能产生影响。从 Djongo 迁移到 Django MongoDB后端时,我们建议您监控性能变化以识别潜在的回归,并在发现任何问题时文件JIRA票证。
例子
以下示例展示了对Recipe 模型及其 嵌入式模型字段(在“嵌入式模型示例”部分中定义)进行定义的MongoDB后端查询和 Djongonutrition 查询之间的差异。该代码查询Nutrition 嵌入式模型的calories 字段。选择Djongo 标签页以查看初始查询,然后选择Django MongoDB Backend 标签页以查看更新后的查询:
Recipe.objects.filter(nutrition__lt={'calories': 500})
Recipe.objects.filter(nutrition__calories__lt=500)
事务
Djongo 和 Django MongoDB后端都支持Django 的原子ACID 事务API功能。但是,它们都提供了自定义API来实现此功能。您可以通过修改代码的 import声明来更新事务以实现 Django MongoDB后端兼容性。
例子
以下示例展示了如何更新代码以导入 Django MongoDB后端的ACID 事务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后端的新应用程序,请参阅入门教程。