## Django backend for MongoDB
Django backend for MongoDB.
Supports:
- Column mappings to MongoDB documents
- Single table (collection) inheritance and single table OneToOne relationships
- Filters (filter/exclude)
## Setup / Configuration
Not supported as primary database, as Django contrib apps rely on Integer primary keys in built in migrations (and
because it is a use case that is not a priority at the moment).
```python
# settings.py
DATABASES = {
# or any other primary databse
"default": {
"ENGINE": "django.db.backends.sqlite3",
"NAME": BASE_DIR / "db.sqlite3",
},
# mongodb database, Client constructor options are passe in 'CLIENT', the database name in 'NAME'
"mongodb": {
"ENGINE": "django_mongodb",
"NAME": "django_mongodb",
"CONN_MAX_AGE": 120,
"CLIENT": {
"host": os.environ.get("MONGODB_URL"),
},
},
}
# A database is required
DATABASE_ROUTERS = ["testproject.router.DatabaseRouter"]
```
Using the database in models requires a DatabaseRouter, which could look like this
```python
class DatabaseRouter:
def db_for_read(self, model, **hints):
if model._meta.app_label == "mymongoapp":
return "default"
return "default"
def db_for_write(self, model, **hints):
if model._meta.app_label == "mymongoapp":
return "default"
return "default"
def allow_relation(self, obj1, obj2, **hints):
if obj1._meta.app_label == obj2._meta.app_label:
return True
return None
def allow_migrate(self, db, app_label, model_name=None, **hints):
if app_label == "mymongoapp":
# we are disabling migrations, as MongoDB is schema-less. Alerts, such as renaming fields, etc. are not supported
return False
return None
```
Finally we are going to change the default primary key of the app using MongoDB (if that is the case, otherwise add
ObjectIdAutoField to the models, where you need it).
```python
# apps.py
class TestappConfig(AppConfig):
default_auto_field = "django_mongodb.models.ObjectIdAutoField"
name = "mymongoapp"
```
### Defining Models
A simple model, in an app, which has `ObjectIdAutoField` as `default_auto_field`
```python
class MyModel(models.Model):
json_field = JSONField()
name = models.CharField(max_length=100)
datetime_field = models.DateTimeField(auto_now_add=True)
time_field = models.TimeField(auto_now_add=True)
date_field = models.DateField(auto_now_add=True)
```
Single table inheritance
```python
class SameTableChild(MyModel):
my_model_ptr = models.OneToOneField(
MyModel,
on_delete=models.CASCADE,
parent_link=True,
related_name="same_table_child",
# pointer to the primary key of the parent model
db_column="_id",
)
extended = models.CharField(max_length=100)
class Meta:
# We are using the parent collection as db_table
db_table = "mymongoapp_mymodel"
```
Single table `OneToOne` relationships
```python
class SameTableOneToOne(models.Model):
dummy_model = models.OneToOneField(
MyModel,
primary_key=True,
on_delete=models.CASCADE,
related_name="extends",
db_column="_id",
)
extra = models.CharField(max_length=100)
class Meta:
# we are using the same collection to persist one-to-one relationships
db_table = "mymongoapp_mymodel"
```
### Querying
```python
# get all objects
MyModel.objects.all()
# get all objects, which have a name in list ["foo", "bar"]
MyModel.objects.filter(name_in=["foo", "bar"])
# select related with single table inheritance and one to one relationships
MyModel.objects.select_related("same_table_child", "extends").all()
# simple aggregations
MyModel.objects.filter(name_in=["foo", "bar"]).count()
# raw mongo filter
MyModel.objects.filter(RawMongoDBQuery({"name": "1"})).delete()
```
### Search
Using the `prefer_search()` extension of MongoQueryset, we can use the `$search` operator of MongoDB to query,
if we have search indexes configured on the model.
```python
MyModel.objects.prefer_search().filter(name="foo").all()
```
PostgreSQL search vectors map down to MongoDB search indexes, so we can use the same syntax as with PostgreSQL.
```python
class MyModel(models.Model):
name = models.CharField(max_length=100)
```
```python
MyModel.objects.annotate(search=SearchVector('name')).filter(search=SearchQuery('foo')).all()
```
### Raw Queries
```python
with connections["mongodb"].cursor() as cursor:
doc = cursor.collections["my_collection"].find_one()
assert isinstance(doc["_id"], ObjectId)
```
Raw data
{
"_id": null,
"home_page": "https://github.com/gersmann/django-mongo-backend",
"name": "django-mongo-backend",
"maintainer": null,
"docs_url": null,
"requires_python": "<4.0,>=3.11",
"maintainer_email": null,
"keywords": "django, mongodb, backend",
"author": "gersmann",
"author_email": null,
"download_url": "https://files.pythonhosted.org/packages/d9/98/d2f572ec9e67f729e220d21dd58793fc3461334d5f6a1cd9ef0f1dffa189/django_mongo_backend-0.27.6.tar.gz",
"platform": null,
"description": "## Django backend for MongoDB\n\nDjango backend for MongoDB.\n\nSupports:\n- Column mappings to MongoDB documents\n- Single table (collection) inheritance and single table OneToOne relationships\n- Filters (filter/exclude)\n\n## Setup / Configuration\n\nNot supported as primary database, as Django contrib apps rely on Integer primary keys in built in migrations (and\nbecause it is a use case that is not a priority at the moment).\n\n```python\n# settings.py\nDATABASES = {\n # or any other primary databse\n \"default\": {\n \"ENGINE\": \"django.db.backends.sqlite3\",\n \"NAME\": BASE_DIR / \"db.sqlite3\",\n },\n # mongodb database, Client constructor options are passe in 'CLIENT', the database name in 'NAME'\n \"mongodb\": {\n \"ENGINE\": \"django_mongodb\",\n \"NAME\": \"django_mongodb\",\n \"CONN_MAX_AGE\": 120,\n \"CLIENT\": {\n \"host\": os.environ.get(\"MONGODB_URL\"),\n },\n },\n}\n# A database is required\nDATABASE_ROUTERS = [\"testproject.router.DatabaseRouter\"]\n```\n\nUsing the database in models requires a DatabaseRouter, which could look like this\n```python\nclass DatabaseRouter:\n def db_for_read(self, model, **hints):\n if model._meta.app_label == \"mymongoapp\":\n return \"default\"\n return \"default\"\n\n def db_for_write(self, model, **hints):\n if model._meta.app_label == \"mymongoapp\":\n return \"default\"\n return \"default\"\n\n def allow_relation(self, obj1, obj2, **hints):\n if obj1._meta.app_label == obj2._meta.app_label:\n return True\n return None\n\n def allow_migrate(self, db, app_label, model_name=None, **hints):\n if app_label == \"mymongoapp\":\n # we are disabling migrations, as MongoDB is schema-less. Alerts, such as renaming fields, etc. are not supported\n return False\n return None\n```\n\nFinally we are going to change the default primary key of the app using MongoDB (if that is the case, otherwise add\nObjectIdAutoField to the models, where you need it).\n\n```python\n# apps.py\nclass TestappConfig(AppConfig):\n default_auto_field = \"django_mongodb.models.ObjectIdAutoField\"\n name = \"mymongoapp\"\n```\n\n### Defining Models\nA simple model, in an app, which has `ObjectIdAutoField` as `default_auto_field`\n\n```python\nclass MyModel(models.Model):\n json_field = JSONField()\n name = models.CharField(max_length=100)\n datetime_field = models.DateTimeField(auto_now_add=True)\n time_field = models.TimeField(auto_now_add=True)\n date_field = models.DateField(auto_now_add=True)\n```\n\nSingle table inheritance\n\n```python\nclass SameTableChild(MyModel):\n my_model_ptr = models.OneToOneField(\n MyModel,\n on_delete=models.CASCADE,\n parent_link=True,\n related_name=\"same_table_child\",\n # pointer to the primary key of the parent model\n db_column=\"_id\",\n )\n extended = models.CharField(max_length=100)\n\n class Meta:\n # We are using the parent collection as db_table\n db_table = \"mymongoapp_mymodel\"\n```\n\nSingle table `OneToOne` relationships\n\n```python\nclass SameTableOneToOne(models.Model):\n dummy_model = models.OneToOneField(\n MyModel,\n primary_key=True,\n on_delete=models.CASCADE,\n related_name=\"extends\",\n db_column=\"_id\",\n )\n extra = models.CharField(max_length=100)\n\n class Meta:\n # we are using the same collection to persist one-to-one relationships\n db_table = \"mymongoapp_mymodel\"\n```\n\n### Querying\n\n```python\n# get all objects\nMyModel.objects.all()\n\n# get all objects, which have a name in list [\"foo\", \"bar\"]\nMyModel.objects.filter(name_in=[\"foo\", \"bar\"])\n\n# select related with single table inheritance and one to one relationships\nMyModel.objects.select_related(\"same_table_child\", \"extends\").all()\n\n# simple aggregations\nMyModel.objects.filter(name_in=[\"foo\", \"bar\"]).count()\n\n# raw mongo filter\nMyModel.objects.filter(RawMongoDBQuery({\"name\": \"1\"})).delete()\n```\n\n### Search\nUsing the `prefer_search()` extension of MongoQueryset, we can use the `$search` operator of MongoDB to query,\nif we have search indexes configured on the model.\n\n```python\nMyModel.objects.prefer_search().filter(name=\"foo\").all()\n```\n\nPostgreSQL search vectors map down to MongoDB search indexes, so we can use the same syntax as with PostgreSQL.\n\n```python\nclass MyModel(models.Model):\n name = models.CharField(max_length=100)\n```\n\n```python\nMyModel.objects.annotate(search=SearchVector('name')).filter(search=SearchQuery('foo')).all()\n```\n\n### Raw Queries\n\n```python\nwith connections[\"mongodb\"].cursor() as cursor:\n doc = cursor.collections[\"my_collection\"].find_one()\n assert isinstance(doc[\"_id\"], ObjectId)\n```\n",
"bugtrack_url": null,
"license": null,
"summary": null,
"version": "0.27.6",
"project_urls": {
"Homepage": "https://github.com/gersmann/django-mongo-backend",
"Repository": "https://github.com/gersmann/django-mongo-backend"
},
"split_keywords": [
"django",
" mongodb",
" backend"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "e14805b909462d42d2b4c691bc9e34acb2d9862bb4d6ac4f920eaf9bcd681304",
"md5": "b1136692f4ed438cb5d92c373883e319",
"sha256": "9391e70619c31d2b8f4e0748d24f6e56df5bb5113724dea14304f908b68fb3ae"
},
"downloads": -1,
"filename": "django_mongo_backend-0.27.6-py3-none-any.whl",
"has_sig": false,
"md5_digest": "b1136692f4ed438cb5d92c373883e319",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "<4.0,>=3.11",
"size": 17571,
"upload_time": "2024-12-10T09:13:54",
"upload_time_iso_8601": "2024-12-10T09:13:54.062808Z",
"url": "https://files.pythonhosted.org/packages/e1/48/05b909462d42d2b4c691bc9e34acb2d9862bb4d6ac4f920eaf9bcd681304/django_mongo_backend-0.27.6-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "d998d2f572ec9e67f729e220d21dd58793fc3461334d5f6a1cd9ef0f1dffa189",
"md5": "c4da6db69ba45cc22ccd042db8b590a1",
"sha256": "6f4e996e06404a12977ed543495547704a67f7318644c5900e19a6ca95f90a9f"
},
"downloads": -1,
"filename": "django_mongo_backend-0.27.6.tar.gz",
"has_sig": false,
"md5_digest": "c4da6db69ba45cc22ccd042db8b590a1",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<4.0,>=3.11",
"size": 15575,
"upload_time": "2024-12-10T09:13:56",
"upload_time_iso_8601": "2024-12-10T09:13:56.754452Z",
"url": "https://files.pythonhosted.org/packages/d9/98/d2f572ec9e67f729e220d21dd58793fc3461334d5f6a1cd9ef0f1dffa189/django_mongo_backend-0.27.6.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-12-10 09:13:56",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "gersmann",
"github_project": "django-mongo-backend",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "django-mongo-backend"
}