diff --git a/README.md b/README.md index 8d08a12a..df944672 100644 --- a/README.md +++ b/README.md @@ -121,9 +121,8 @@ DATABASES = { `OPTIONS` is an optional dictionary of parameters that will be passed to [`MongoClient`](https://pymongo.readthedocs.io/en/stable/api/pymongo/mongo_client.html). -Alternatively, those that follow the [twelve-factor app]( -https://www.12factor.net/backing-services) methodology can configure Django's -`DATABASES` with `django_mongodb.parse_uri(MONGODB_URI)`: +Alternatively, if you prefer to simply paste in a MongoDB URI rather than +parsing it into the format above, you can use: ```python import django_mongodb @@ -132,22 +131,12 @@ MONGODB_URI = "mongodb+srv://myDatabaseUser:D1fficultP%40ssw0rd@cluster0.example DATABASES["default"] = django_mongodb.parse_uri(MONGODB_URI) ``` -#### Additional `parse_uri` options +#### `django_mongodb.parse_uri(uri, conn_max_age=0, conn_health_checks=False, test=None)` -The `parse_uri` function accepts these keyword arguments: - -| Keyword argument | Default setting | -| -------------------- | --------------------- | -| `conn_max_age` | `0` | -| `conn_health_checks` | `False` | -| `test` | `None` | - -- The `conn_max_age` and `conn_health_checks` options can be used with - [persistent database connections]( - https://docs.djangoproject.com/en/latest/ref/databases/#persistent-database-connections). - -- The `test` option can be used to provide a dictionary of [settings for test databases]( - https://docs.djangoproject.com/en/latest/ref/settings/#test). +- Use `conn_max_age` and `conn_health_checks` to configure [persistent database + connections](https://docs.djangoproject.com/en/stable/ref/databases/#persistent-database-connections). +- Use `test` to provide a dictionary of [settings for test databases]( + https://docs.djangoproject.com/en/stable/ref/settings/#test). Congratulations, your project is ready to go! diff --git a/django_mongodb/utils.py b/django_mongodb/utils.py index 759d7c11..40a1d1e2 100644 --- a/django_mongodb/utils.py +++ b/django_mongodb/utils.py @@ -28,16 +28,12 @@ def check_django_compatability(): def parse_uri(uri, conn_max_age=0, conn_health_checks=False, test=None): """ - Parse a MongoDB URI and return a dictionary of Django database - settings. This function is a wrapper around PyMongo's - ``pymongo.uri_parser.parse_uri()`` function that converts PyMongo's - settings dictionary into a Django database settings dictionary. + Convert the given uri into a dictionary suitable for Django's DATABASES + setting. """ uri = parse_uri_mongo(uri) - host = None port = None - if uri["fqdn"] is not None: # If the fqdn is present, this is a SRV URI and the host is the fqdn. host = f"mongodb+srv://{uri['fqdn']}" @@ -47,7 +43,6 @@ def parse_uri(uri, conn_max_age=0, conn_health_checks=False, test=None): host, port = nodelist[0] elif len(nodelist) > 1: host = ",".join([f"{host}:{port}" for host, port in nodelist]) - settings_dict = { "ENGINE": "django_mongodb", "NAME": uri["database"], @@ -59,10 +54,8 @@ def parse_uri(uri, conn_max_age=0, conn_health_checks=False, test=None): "CONN_MAX_AGE": conn_max_age, "CONN_HEALTH_CHECKS": conn_health_checks, } - if test: settings_dict["TEST"] = test - return settings_dict diff --git a/tests/utils_/test_parse.py b/tests/utils_/test_parse_uri.py similarity index 63% rename from tests/utils_/test_parse.py rename to tests/utils_/test_parse_uri.py index d7e054ec..5b931aec 100644 --- a/tests/utils_/test_parse.py +++ b/tests/utils_/test_parse_uri.py @@ -3,16 +3,12 @@ import pymongo from django.test import SimpleTestCase -import django_mongodb +from django_mongodb import parse_uri URI = "mongodb+srv://myDatabaseUser:D1fficultP%40ssw0rd@cluster0.example.mongodb.net/myDatabase?retryWrites=true&w=majority&tls=false" -class MongoParseURITests(SimpleTestCase): - """ - Test django_mongodb.parse_uri(uri) function - """ - +class ParseURITests(SimpleTestCase): def setUp(self): self.srv_record = MagicMock() self.srv_record.target.to_text.return_value = "cluster0.example.mongodb.net" @@ -21,53 +17,58 @@ def setUp(self): self.addCleanup(self.patcher.stop) @patch("dns.resolver.resolve") - def test_uri(self, mock_resolver): - settings_dict = django_mongodb.parse_uri( - "mongodb://cluster0.example.mongodb.net/myDatabase" - ) + def test_simple_uri(self, mock_resolver): + settings_dict = parse_uri("mongodb://cluster0.example.mongodb.net/myDatabase") self.assertEqual(settings_dict["ENGINE"], "django_mongodb") self.assertEqual(settings_dict["NAME"], "myDatabase") self.assertEqual(settings_dict["HOST"], "cluster0.example.mongodb.net") + @patch("dns.resolver.resolve") + def test_no_database(self, mock_resolver): + settings_dict = parse_uri("mongodb://cluster0.example.mongodb.net/") + self.assertEqual(settings_dict["ENGINE"], "django_mongodb") + self.assertIsNone(settings_dict["NAME"]) + self.assertEqual(settings_dict["HOST"], "cluster0.example.mongodb.net") + @patch("dns.resolver.resolve") def test_srv_uri_with_options(self, mock_resolver): - settings_dict = django_mongodb.parse_uri(URI) + settings_dict = parse_uri(URI) self.assertEqual(settings_dict["ENGINE"], "django_mongodb") self.assertEqual(settings_dict["NAME"], "myDatabase") self.assertEqual(settings_dict["HOST"], "mongodb+srv://cluster0.example.mongodb.net") self.assertEqual(settings_dict["USER"], "myDatabaseUser") self.assertEqual(settings_dict["PASSWORD"], "D1fficultP@ssw0rd") - self.assertEqual(settings_dict["PORT"], None) + self.assertIsNone(settings_dict["PORT"]) self.assertEqual( settings_dict["OPTIONS"], {"retryWrites": True, "w": "majority", "tls": False} ) def test_localhost(self): - settings_dict = django_mongodb.parse_uri("mongodb://localhost/myDatabase") + settings_dict = parse_uri("mongodb://localhost/myDatabase") self.assertEqual(settings_dict["ENGINE"], "django_mongodb") self.assertEqual(settings_dict["NAME"], "myDatabase") self.assertEqual(settings_dict["HOST"], "localhost") - def test_localhost_bad_credentials(self): - with self.assertRaises(pymongo.errors.InvalidURI): - django_mongodb.parse_uri("mongodb://:@localhost/myDatabase") - @patch("dns.resolver.resolve") - def test_conn_max_age_kwarg(self, mock_resolver): - settings_dict = django_mongodb.parse_uri(URI, conn_max_age=600) + def test_conn_max_age(self, mock_resolver): + settings_dict = parse_uri(URI, conn_max_age=600) self.assertEqual(settings_dict["CONN_MAX_AGE"], 600) @patch("dns.resolver.resolve") - def test_conn_health_checks_kwarg(self, mock_resolver): - settings_dict = django_mongodb.parse_uri(URI, conn_health_checks=True) + def test_conn_health_checks(self, mock_resolver): + settings_dict = parse_uri(URI, conn_health_checks=True) self.assertEqual(settings_dict["CONN_HEALTH_CHECKS"], True) @patch("dns.resolver.resolve") def test_test_kwarg(self, mock_resolver): - settings_dict = django_mongodb.parse_uri(URI, test={"NAME": "test_db"}) + settings_dict = parse_uri(URI, test={"NAME": "test_db"}) self.assertEqual(settings_dict["TEST"]["NAME"], "test_db") + def test_invalid_credentials(self): + with self.assertRaises(pymongo.errors.InvalidURI): + parse_uri("mongodb://:@localhost/myDatabase") + @patch("dns.resolver.resolve") - def test_uri_no_prefix(self, mock_resolver): + def test_no_prefix(self, mock_resolver): with self.assertRaises(pymongo.errors.InvalidURI): - django_mongodb.parse_uri("cluster0.example.mongodb.net/myDatabase") + parse_uri("cluster0.example.mongodb.net/myDatabase")