Package: pydjantic
pydjanticUse Pydantic Settings in your Django application.IntroductionIf you are tired of the mess in your Django Settings - I feel your pain:Ridiculously longsettings.pyfile, with ASCII-art separationfrom common import *Pythonanti-patterntry: <import> except: ImportErrorPythonanti-patternbase.py,production.py,local.py,domain.py- bunch of unrelated modules that override each otherdjango-environlibrary, that do even worse...On the other hand we havePydantic Settings,
which is de-facto standard for all non-django projects.If you love Pydantic settings management approach,Pydjanticis a right tool for you.Pydjanticallows you to define your settings in familiar way - just inherit fromBaseSettings:fromtypingimportListfrompydanticimportBaseSettings,Fieldfrompydantic.fieldsimportUndefinedfrompydjanticimportto_djangoclassGeneralSettings(BaseSettings):SECRET_KEY:str=Field(default=Undefined,env='DJANGO_SECRET_KEY')DEBUG:bool=Field(default=False,env='DEBUG')INSTALLED_APPS:List[str]=['django.contrib.admin','django.contrib.auth',]LANGUAGE_CODE:str='en-us'USE_TZ:bool=TrueclassStaticSettings(BaseSettings):STATIC_URL:str='/static/'STATIC_ROOT:str='staticfiles'classSentrySettings(BaseSettings):SENTRY_DSN:str=Field(default=Undefined,env='SENTRY_DSN')classProjectSettings(GeneralSettings,StaticSettings,SentrySettings):passto_django(ProjectSettings())You can create as many classes/modules as you want, to achieve perfect settings' management.
Divide your settings by domains, and then create finalProjectSettingsclass, that inherits from these domains.Provide the instance ofProjectSettingstoto_djangofunction.
That's all, your django settings will work as expected.InstallationInstall usingpip install -U pydjanticorpoetry add pydjantic.ExampleIn the/demodirectory you can find aworking Django appwithpydjantic settings.Database configurationPydjanticcomes with a special helper for managing DB configs -BaseDBConfig. See example below:frompydanticimportField,PostgresDsnfrompydjanticimportBaseDBConfigclassDatabaseConfig(BaseDBConfig):default:PostgresDsn=Field(default="postgres://user:password@hostname:5432/dbname",env="DATABASE_URL")db_settings=DatabaseConfig()assertdb_settings.default=={'CONN_MAX_AGE':0,'ENGINE':'django.db.backends.postgresql_psycopg2','HOST':'hostname','NAME':'dbname','PASSWORD':'password','PORT':5432,'USER':'user',}Also, you can define database configurations directly:frompydanticimportBaseSettings,FieldclassPostgresDB(BaseSettings):ENGINE:str='django.db.backends.postgresql_psycopg2'HOST:str=Field(default='localhost',env='DATABASE_HOST')NAME:str=Field(default='dbname',env='DATABASE_NAME')PASSWORD:str=Field(default='password',env='DATABASE_PASSWORD')PORT:int=Field(default=5432,env='DATABASE_PORT')USER:str=Field(default='user',env='DATABASE_USER')OPTIONS:dict=Field(default={},env='DATABASE_OPTIONS')CONN_MAX_AGE:int=Field(default=0,env='DATABASE_CONN_MAX_AGE')classDatabaseConfig(BaseSettings):default=PostgresDB()Or mix these approaches:classDatabaseConfig(BaseDBConfig):default=Field(default="postgres://user:password@hostname:5432/dbname")replica=PostgresDB()For more examples seetests.Transformation from dsn to django format is done bydj-database-urllibrary.