Как передать настройки конфигурации в Django и сохранить развязку модулей?

В проекте Python Django у меня есть модуль с классом (допустим SomeDataStore), который абстрагирует поведение хранилища файлов и требует настройки конфигурации с правильным путем (разным для разработки, prod, ...)

В настоящее время я делаю это следующим образом:

# settings.py
RELEVANT_PATH = os.environ.get("DJANGO_RELEVANT_PATH", "/some/default")
...

# datastore.py
from django.conf import settings
class SomeDataStore:
    def list_files(self):
        p = Path(settings.RELEVANT_PATH) 
        files = p.glob("*.csv")
        return files
    ...

# views.py
from datastatus import SomeDataStore
def show_files(request):
    files = SomeDataStore().get_files()
    ...

Цель: Я хотел бы полностью отделить модуль datastore.py от django, чтобы его можно было легко использовать отдельно. Это означало бы избавиться от использования django.conf.settings в datastore.py

Одним из очевидных способов сделать это было бы предоставление пути в качестве параметра init класса DataStore.

# datastore.py
class SomeDataStore:
    def __init__(self, path) -> None:
        self.path=path
    ...

Однако я использую этот DataStore во многих представлениях Django, и это потребует от меня всегда указывать путь при инстанцировании класса, например, так

# views.py
from datastatus import SomeDataStore
def show_files(request):
    files = SomeDataStore(settings.RELEVANT_PATH).get_files()
    ...

def show_something_else(request):
    somethings = SomeDataStore(settings.RELEVANT_PATH).get_something_else()
    ...

Я хотел бы избежать необходимости в каждой инстанциации всегда указывать настройки конфигурации для пути.

Вопрос: Есть ли какой-то чистый способ, шаблон или подход для решения этой проблемы в Django? Или я упускаю из виду что-то очевидное?

Вы можете иметь my_settings.py, удерживающий PATH:

# my_settings.py
import os
RELEVANT_PATH = os.environ.get("whatever", "/some/default")

и использовать как

# datastore.py
from my_settings import RELEVANT_PATH

class SomeDataStore:
    def list_files(self):
        p = Path(RELEVANT_PATH) 
        files = p.glob("*.csv")
        return files
    ...

В случае, если вам нужен этот путь в Django в другом месте, вы можете иметь этот путь как часть settings.py также

# settings.py
from my_settings import RELEVANT_PATH as my_relevant_path

RELEVANT_PATH = my_relevant_path

# usage in other django app files
from django.conf import settings
# use settings.RELEVANT_PATH as usual

Это обеспечит некоторую развязку, и вы сможете изменить путь в одном месте my_settings.py и импортировать путь вне django, а также использовать его внутри django с обычным синтаксисом django.conf.settings.xx.

Вернуться на верх