1111from pymongo .collection import Collection
1212from pymongo .driver_info import DriverInfo
1313from pymongo .mongo_client import MongoClient
14+ from pymongo .uri_parser import parse_uri
1415
1516from . import __version__ as django_mongodb_backend_version
1617from . import dbapi as Database
@@ -157,6 +158,18 @@ def __init__(self, settings_dict, alias=DEFAULT_DB_ALIAS):
157158 self .in_atomic_block_mongo = False
158159 # Current number of nested 'atomic' calls.
159160 self .nested_atomics = 0
161+ # If database "NAME" isn't specified, try to get it from HOST, if it's
162+ # a connection string.
163+ if self .settings_dict ["NAME" ] == "" : # Empty string = unspecified; None = _nodb_cursor()
164+ name_is_missing = True
165+ host = self .settings_dict ["HOST" ]
166+ if host .startswith (("mongodb://" , "mongodb+srv://" )):
167+ uri = parse_uri (host )
168+ if database := uri .get ("database" ):
169+ self .settings_dict ["NAME" ] = database
170+ name_is_missing = False
171+ if name_is_missing :
172+ raise ImproperlyConfigured ('settings.DATABASES is missing the "NAME" value.' )
160173
161174 def get_collection (self , name , ** kwargs ):
162175 collection = Collection (self .database , name , ** kwargs )
@@ -183,15 +196,19 @@ def init_connection_state(self):
183196
184197 def get_connection_params (self ):
185198 settings_dict = self .settings_dict
186- if not settings_dict ["NAME" ]:
187- raise ImproperlyConfigured ('settings.DATABASES is missing the "NAME" value.' )
188- return {
199+ params = {
189200 "host" : settings_dict ["HOST" ] or None ,
190- "port" : int (settings_dict ["PORT" ] or 27017 ),
191- "username" : settings_dict .get ("USER" ),
192- "password" : settings_dict .get ("PASSWORD" ),
193201 ** settings_dict ["OPTIONS" ],
194202 }
203+ # MongoClient uses any of these parameters (including "OPTIONS" above)
204+ # to override any corresponding values in a connection string "HOST".
205+ if user := settings_dict .get ("USER" ):
206+ params ["username" ] = user
207+ if password := settings_dict .get ("PASSWORD" ):
208+ params ["password" ] = password
209+ if port := settings_dict .get ("PORT" ):
210+ params ["port" ] = int (port )
211+ return params
195212
196213 @async_unsafe
197214 def get_new_connection (self , conn_params ):
0 commit comments