Alkalmazás szintű konfiguráció

Ahogy azt már tudjuk, Djangonál a beállításokat a settings.py modulba illik tenni. Viszont mit tegyünk akkor, ha egy olyan alkalmazást (appot) szeretnénk készíteni, amit majd több más projektben is fel szeretnénk használni, esetleg közkinccsé is tesszük?

Ilyenkor persze az is megoldás, ha szépen leírjuk a dokumentációban, hogy milyen dolgokat állítson be az emberünk a settings.py-ben, és mi mit ajánlunk alapértelmezetten, vagy a kódunkban bárhol ahol szeretnénk használni ezeket a beállításokat, ott mindig ellenőrizzük, hogy be van-e állítva, és ha nincs, akkor az alapértelmezettet használjuk. De ezek nem túl szép megoldások.

Én személy szerint úgy oldom meg a dolgot, hogy csinálok egy alkalmazás szintű settings.py modult, és ide begyűjtöm a django.conf.settings-ből a számomra fontos dolgokat, majd később a kódomban csak ezt a saját settings modult használom. Így a webalkalmazás indulásakor be tudom állítani a meg nem adott értékeknek az alapértelmezettet, illetve hibával tudom jelezni azonnal, ha valami fontos dolog nincs beállítva - az ilyen hiba a hagyományos django.conf.settings használata estén rejtve maradhatna mindaddig, amíg rá nem futunk egy olyan kódrészre, ahol szükség lenne az adott beállításra.

Íme, hogyan néz ki a djkeptar projektem keptar alkalmazásának settings.py modulja:

from django.conf import settings
from django.core.exceptions import ImproperlyConfigured

# root of the gallery where the images are store on the filesystem
KEPTAR_ROOT = getattr(settings, 'KEPTAR_ROOT', None)
if KEPTAR_ROOT is None:
    raise ImproperlyConfigured('Please make sure you specified a KEPTAR_ROOT setting.')

# absolute or relative url to reach the images via http (to support static webservers)
KEPTAR_URL = getattr(settings, 'KEPTAR_URL', None)
if KEPTAR_URL is None:
    raise ImproperlyConfigured('Please make sure you specified a KEPTAR_URL setting.')

# supported file extensions
KEPTAR_EXTENSIONS = getattr(settings, 'KEPTAR_EXTENSIONS', ['jpg','jpeg','png'])

# thumbnail sizes and folders
KEPTAR_THUMBS = getattr(settings, 'KEPTAR_THUMBS', {
        '': { 'dir': '.tn', 'size': (120,120) },
        'blog': { 'dir': '.tn/blog', 'size': (600,600) },
        })

# show hidden files (files starting with '.')
KEPTAR_SHOW_HIDDEN = getattr(settings, 'KEPTAR_SHOW_HIDDEN', False)

# icon locations (url)
KEPTAR_ICONS = getattr(settings, 'KEPTAR_ICONS', {
        'dir': '/media/keptar/icons/tn_dir.jpg',
        })

Semmi ördöngösség nincs benne, ha valami fontos dolog nincs beállítva a settings.py-ben, akkor exceptiont dobunk, ha valami kevésbé fontos, akkor ahhoz hozzárendelünk valami alapértelmezett értéket. És mindehhez egyedül a getattr beépített python függvényre van szükségünk. Annyi a dolgunk ezután, hogy a saját settings modulunkat használjuk a központi helyett, pl:

# reszlet a keptar/utils.py modulbol
# "from django.conf import settings" helyett:
from keptar import settings

def get_abspath(path):
    abspath = os.path.abspath(os.path.join(settings.KEPTAR_ROOT, path))
    if not abspath.startswith(settings.KEPTAR_ROOT):
        raise AccessDenied("%s < %s" % (abspath, settings.KEPTAR_ROOT))

    return abspath

Egyszerű, mint a bot. Ti hogy szoktátok?

Itt jegyezném meg, hogy én egyébként ezt a django-s megközelítést nemnagyon szeretem - mármint, hogy egy kvázi globális objektumba dobáljuk bele a beállításokat, mint propertyket, ráadásul úgy, hogy azt véletlenül még módosítani is lehet. Szerintem szebb lenne valami dependency injection szerű megoldást használni, bár a jelenlegi megoldás előnye ezekkel szemben, hogy sokkal egyszerűbb, és azért nagy butaságot kell ahhoz csinálni, hogy valami elromoljon miatta.

26okt.

2 Comment for Alkalmazás szintű konfiguráció

  1. slink says:
    Eric Florenzano Why Django Sucks, and How we Can Fix it c. előadásában érinti a djangos megoldás hátrányait.

Szólj hozzá