django-cfg 1.1.54__py3-none-any.whl → 1.1.55__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
django_cfg/__init__.py CHANGED
@@ -38,7 +38,7 @@ default_app_config = "django_cfg.apps.DjangoCfgConfig"
38
38
  from typing import TYPE_CHECKING
39
39
 
40
40
  # Version information
41
- __version__ = "1.1.54"
41
+ __version__ = "1.1.55"
42
42
  __author__ = "Unrealos Team"
43
43
  __email__ = "info@unrealos.com"
44
44
  __license__ = "MIT"
Binary file
@@ -192,7 +192,9 @@ class SettingsGenerator:
192
192
  for alias, db_config in config.databases.items():
193
193
  if db_config.has_routing_rules():
194
194
  for app in db_config.apps:
195
- routing_rules[app] = alias
195
+ # Extract app_label from full path (e.g., "apps.knowbase" -> "knowbase")
196
+ app_label = app.split('.')[-1] if '.' in app else app
197
+ routing_rules[app_label] = alias
196
198
 
197
199
  if routing_rules:
198
200
  settings["DATABASE_ROUTERS"] = ["django_cfg.routers.DatabaseRouter"]
django_cfg/routers.py CHANGED
@@ -5,6 +5,7 @@ Simple and reliable database routing.
5
5
  """
6
6
 
7
7
  from django.conf import settings
8
+ from django.apps import apps
8
9
 
9
10
 
10
11
  class DatabaseRouter:
@@ -14,35 +15,69 @@ class DatabaseRouter:
14
15
  Uses DATABASE_ROUTING_RULES setting to determine which apps
15
16
  should use which databases.
16
17
  """
18
+
19
+ def _get_database_for_app(self, app_label):
20
+ """
21
+ Get database for app_label, trying multiple approaches.
22
+
23
+ 1. Direct app_label lookup
24
+ 2. Find full app path and lookup
25
+ """
26
+ rules = getattr(settings, 'DATABASE_ROUTING_RULES', {})
27
+
28
+ # Try direct app_label first
29
+ if app_label in rules:
30
+ return rules[app_label]
31
+
32
+ # Try to find full app path using Django's app registry
33
+ try:
34
+ app_config = apps.get_app_config(app_label)
35
+ app_module = app_config.module.__name__
36
+
37
+ # Check if full module path is in rules
38
+ if app_module in rules:
39
+ return rules[app_module]
40
+
41
+ except LookupError:
42
+ pass
43
+
44
+ return None
17
45
 
18
46
  def db_for_read(self, model, **hints):
19
47
  """Route reads to correct database."""
20
- rules = getattr(settings, 'DATABASE_ROUTING_RULES', {})
21
- return rules.get(model._meta.app_label)
48
+ return self._get_database_for_app(model._meta.app_label)
22
49
 
23
50
  def db_for_write(self, model, **hints):
24
51
  """Route writes to correct database."""
25
- rules = getattr(settings, 'DATABASE_ROUTING_RULES', {})
26
- return rules.get(model._meta.app_label)
52
+ return self._get_database_for_app(model._meta.app_label)
27
53
 
28
54
  def allow_relation(self, obj1, obj2, **hints):
29
- """Allow relations between same database."""
30
- rules = getattr(settings, 'DATABASE_ROUTING_RULES', {})
31
- db1 = rules.get(obj1._meta.app_label)
32
- db2 = rules.get(obj2._meta.app_label)
33
- return db1 == db2 if db1 and db2 else None
55
+ """Allow relations between databases."""
56
+ app_label1 = obj1._meta.app_label
57
+ app_label2 = obj2._meta.app_label
58
+
59
+ db1 = self._get_database_for_app(app_label1)
60
+ db2 = self._get_database_for_app(app_label2)
61
+
62
+ # Allow relations if both are in same database
63
+ if db1 and db2:
64
+ return db1 == db2
65
+
66
+ # Allow relations between routed apps and default database
67
+ # (e.g., User from default can relate to Document from knowbase)
68
+ if (db1 and not db2) or (db2 and not db1):
69
+ return True
70
+
71
+ # Allow all other relations (both in default)
72
+ return True
34
73
 
35
74
  def allow_migrate(self, db, app_label, **hints):
36
75
  """Allow migrations to correct database."""
37
- rules = getattr(settings, 'DATABASE_ROUTING_RULES', {})
38
- target_db = rules.get(app_label)
76
+ target_db = self._get_database_for_app(app_label)
39
77
 
40
78
  if target_db:
41
79
  # This app IS configured in the rules
42
80
  return db == target_db
43
- elif db in rules.values():
44
- # This app is NOT configured, but the target DB is used by other apps
81
+ else:
82
+ # This app is NOT configured, allow migration to default only
45
83
  return db == 'default'
46
-
47
- # Allow migration to default
48
- return None
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: django-cfg
3
- Version: 1.1.54
3
+ Version: 1.1.55
4
4
  Summary: 🚀 Production-ready Django configuration framework with type-safe settings, smart automation, and modern developer experience
5
5
  Project-URL: Homepage, https://github.com/markolofsen/django-cfg
6
6
  Project-URL: Documentation, https://django-cfg.readthedocs.io
@@ -1,8 +1,8 @@
1
- django_cfg/__init__.py,sha256=YZogs5kyytXzUOnW3xvppcMf0B__-iElityi3otj7qE,14288
1
+ django_cfg/__init__.py,sha256=ZTcmv4CICkfINCwJpvyAB07eMvcwno-wz_5ySOgJ6QM,14288
2
2
  django_cfg/apps.py,sha256=k84brkeXJI7EgKZLEpTkM9YFZofKI4PzhFOn1cl9Msc,1656
3
3
  django_cfg/exceptions.py,sha256=RTQEoU3PfR8lqqNNv5ayd_HY2yJLs3eioqUy8VM6AG4,10378
4
4
  django_cfg/integration.py,sha256=-7hvd-4ohLdzH4eufCZTOe3yTzPoQyB_HCfvsSm9AAw,5218
5
- django_cfg/routers.py,sha256=J89kcIArV2lSl3rzh61Rya0h-I5Zq7-QAat6PvmKVFs,1582
5
+ django_cfg/routers.py,sha256=O954Hm1BKMyN9-tIK2SByxTHafy_SGzbHLjCbBaf4lg,2622
6
6
  django_cfg/version_check.py,sha256=jI4v3YMdQriUEeb_TvRl511sDghy6I75iKRDUaNpucs,4800
7
7
  django_cfg/apps/__init__.py,sha256=JtDmEYt1OcleWM2ZaeX0LKDnRQzPOavfaXBWG4ECB5Q,26
8
8
  django_cfg/apps/urls.py,sha256=aQemCAjtBYZJwGqb5Az_kiZ_43bJTLH74EZjn_A40Vw,2125
@@ -135,7 +135,7 @@ django_cfg/apps/tasks/templates/tasks/components/tab_navigation.html,sha256=Sxb7
135
135
  django_cfg/apps/tasks/templates/tasks/components/task_details_modal.html,sha256=DeJjj3dxYcBEAj8Hv4Ii4koEMaNRVHta9_R25qZyK4w,6317
136
136
  django_cfg/apps/tasks/templates/tasks/components/tasks_tab.html,sha256=Yd6SPgdQX1p_6miitu3nZHjdZOtbsXMhUP4DnXSntPs,1826
137
137
  django_cfg/apps/tasks/templates/tasks/components/workers_tab.html,sha256=4Ud4QpG6bnxBsrBDKGXdy4GcIne43wC13Ch1szZzrbo,1580
138
- django_cfg/archive/django_sample.zip,sha256=9ZkmIjiQEWf9dYHet1BHVKuQWO1dHwp8rfJbOEa8fhc,624553
138
+ django_cfg/archive/django_sample.zip,sha256=BWQUWaM6yP4q-oL2JsAi2dQhY1fdZvFqtRt9tJ5_uCI,624553
139
139
  django_cfg/cli/README.md,sha256=m0pkw3h-g_dJ4wU1N5eMxQP_ecGUDTM_3l0tDNDxByQ,11669
140
140
  django_cfg/cli/__init__.py,sha256=i3ksFngCqZCBvaimQcBD1P2_gr5PiM--4efLScCjvvU,152
141
141
  django_cfg/cli/main.py,sha256=6PfG3ec2AmPHLmUGYc472CId1gs8cRKYrHcvd3ECPxU,998
@@ -146,7 +146,7 @@ django_cfg/cli/commands/info.py,sha256=tLZmiZX2nEpwrcN9cUwrGKb95X7dasuoeePrqTmK2
146
146
  django_cfg/core/__init__.py,sha256=eVK57qFOok9kTeHoNEMQ1BplkUOaQ7NB9kP9eQK1vg0,358
147
147
  django_cfg/core/config.py,sha256=EO6l39BncNRnvxkWHqyGNAiP-rhoAfwtBtr_UmWLYL8,27799
148
148
  django_cfg/core/environment.py,sha256=AXNKVxcV_3_3gtlafDx3wFTnTPPMGQ9gl40vYm2w-Hg,9101
149
- django_cfg/core/generation.py,sha256=z4yDoYM-_q6RGIn4ZesLXS8frcHoiHz5oBIREcJON4U,24668
149
+ django_cfg/core/generation.py,sha256=zClvEA0Qq_uMaIJ-2TjacdgldHH9KwNoKRMKSjJV2o0,24849
150
150
  django_cfg/core/validation.py,sha256=j0q57oJEJjI6ylb3AzvsgupmvBKsUcrxpmkfKF3ZRF4,6585
151
151
  django_cfg/management/__init__.py,sha256=z8p1jlyajNUleDxRUXL3iXUI99xXWFYNtFAe5nKy1kA,43
152
152
  django_cfg/management/commands/__init__.py,sha256=z8p1jlyajNUleDxRUXL3iXUI99xXWFYNtFAe5nKy1kA,43
@@ -251,8 +251,8 @@ django_cfg/templates/emails/base_email.html,sha256=TWcvYa2IHShlF_E8jf1bWZStRO0v8
251
251
  django_cfg/utils/__init__.py,sha256=64wwXJuXytvwt8Ze_erSR2HmV07nGWJ6DV5wloRBvYE,435
252
252
  django_cfg/utils/path_resolution.py,sha256=eML-6-RIGTs5TePktIQN8nxfDUEFJ3JA0AzWBcihAbs,13894
253
253
  django_cfg/utils/smart_defaults.py,sha256=iL6_n3jGDW5812whylWAwXik0xBSYihdLp4IJ26T5eA,20547
254
- django_cfg-1.1.54.dist-info/METADATA,sha256=OlemLNWZct6A8IOV06tZcAVaGSqDIvP96Qf2yjkz5r0,38953
255
- django_cfg-1.1.54.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
256
- django_cfg-1.1.54.dist-info/entry_points.txt,sha256=Ucmde4Z2wEzgb4AggxxZ0zaYDb9HpyE5blM3uJ0_VNg,56
257
- django_cfg-1.1.54.dist-info/licenses/LICENSE,sha256=xHuytiUkSZCRG3N11nk1X6q1_EGQtv6aL5O9cqNRhKE,1071
258
- django_cfg-1.1.54.dist-info/RECORD,,
254
+ django_cfg-1.1.55.dist-info/METADATA,sha256=yjqg7Vz6T_N9tMe_gdeqTzxEV7jo-vZH8nKbH4eHies,38953
255
+ django_cfg-1.1.55.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
256
+ django_cfg-1.1.55.dist-info/entry_points.txt,sha256=Ucmde4Z2wEzgb4AggxxZ0zaYDb9HpyE5blM3uJ0_VNg,56
257
+ django_cfg-1.1.55.dist-info/licenses/LICENSE,sha256=xHuytiUkSZCRG3N11nk1X6q1_EGQtv6aL5O9cqNRhKE,1071
258
+ django_cfg-1.1.55.dist-info/RECORD,,