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.
Amit egyebkent mindenkinek javaslok atnezesre, illetve itt van videon is, nagyon egyet tudok vele erteni, es remelem szepen lassan elmozdulnak arra a dolgok, amiket javasol.
Es esely van ra, hisz ha visszanezzuk Cal Henderson Why I Hate Django c. eloadasat meg a 2008-as DjangoCon-rol, akkor azert orommel tapasztalhatjuk, hogy mara par dolgot "megszereltek" a sracok.