1

In a Python Django project, I have a module with a class (let's say SomeDataStore) that abstracts file storage behaviour and requires a config setting with the correct path (different for development, prod, ...)

Currently, I've done it like this:

# 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()
    ...

Goal: I'd like to decouple the datastore.py module completely from django, so that it can easily be used standalone. That would mean to get rid of the django.conf.settings usage in datastore.py

One obvious way to do it would be to provide the path as an init parameter to the DataStore class.

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

However, I use this DataStore in many Django views, and that would require me to always specify the path when instantiating the class, e.g. like so

# 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()
    ...

I'd like to avoid the need in each instantiation to always specify the config setting for the path.

Question: Is there some clean way, pattern or approach to deal with this in Django? Or am I overlooking something obvious here?

Something I thought of is instantiating the DataStore in settings.py, but creating objects in settings.py seems bloating it. Or isn't it?

Rabarberski
  • 23,854
  • 21
  • 74
  • 96

1 Answers1

1

You could have a my_settings.py holding the PATH:

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

and use like

# datastore.py
from my_settings import RELEVANT_PATH

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

In case you need this path whithin Django elsewhere, you could have this path as part of settings.py as well

# 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

This would provide for some decoupling and you can change the path at a single place my_settings.py and import the path outside django as well as use it inside django with the usual django.conf.settings.xx syntax.

Nechoj
  • 1,512
  • 1
  • 8
  • 18