Coverage for src/settings.py: 100%

63 statements  

« prev     ^ index     » next       coverage.py v7.9.2, created at 2025-08-04 12:59 +0300

1import os 

2from pathlib import Path 

3from datetime import timedelta 

4 

5from django.utils.translation import gettext_lazy as _ 

6from decouple import config 

7 

8import cloudinary 

9import cloudinary.uploader 

10import cloudinary.api 

11 

12import sentry_sdk 

13 

14from .unfold import UNFOLD 

15 

16BASE_DIR = Path(__file__).resolve().parent.parent 

17 

18SECRET_KEY = os.getenv('SECRET_KEY', config('SECRET_KEY')) 

19 

20DEBUG = os.getenv('DEBUG', config('DEBUG')) == 'True' 

21 

22ALLOWED_HOSTS = os.getenv('ALLOWED_HOSTS', config('ALLOWED_HOSTS')).split(',') 

23 

24CSRF_TRUSTED_ORIGINS = os.getenv( 

25 'CSRF_TRUSTED_ORIGINS', config('CSRF_TRUSTED_ORIGINS', []) 

26).split(',') 

27 

28CORS_ALLOWED_ORIGINS = os.getenv( 

29 'CORS_ALLOWED_ORIGINS', config('CORS_ALLOWED_ORIGINS') 

30).split(',') 

31 

32 

33# Custom Django applications in this project 

34PROJECT_APPS = [ 

35 'src.accounts', 

36 'src.common', 

37 'src.products', 

38 'src.shopping_bags', 

39 'src.wishlists', 

40 'src.orders', 

41] 

42 

43INSTALLED_APPS = [ 

44 'unfold', 

45 'unfold.contrib.filters', 

46 'unfold.contrib.forms', 

47 'cloudinary', 

48 'cloudinary_storage', 

49 'django_celery_beat', 

50 'daphne', 

51 'django.contrib.admin', 

52 'django.contrib.auth', 

53 'django.contrib.contenttypes', 

54 'django.contrib.sessions', 

55 'django.contrib.messages', 

56 'django.contrib.staticfiles', 

57 'rest_framework', 

58 'rest_framework_simplejwt', 

59 'rest_framework_simplejwt.token_blacklist', 

60 'corsheaders', 

61] + PROJECT_APPS 

62 

63ASGI_APPLICATION = 'src.asgi.application' 

64 

65REST_FRAMEWORK = { 

66 'DEFAULT_AUTHENTICATION_CLASSES': [ 

67 'rest_framework_simplejwt.authentication.JWTAuthentication', 

68 ], 

69 'DEFAULT_PERMISSION_CLASSES': [ 

70 'rest_framework.permissions.IsAuthenticated', 

71 ], 

72} 

73 

74SIMPLE_JWT = { 

75 'ACCESS_TOKEN_LIFETIME': timedelta(minutes=15), 

76 'REFRESH_TOKEN_LIFETIME': timedelta(days=7), 

77} 

78 

79MIDDLEWARE = [ 

80 'corsheaders.middleware.CorsMiddleware', 

81 'django.middleware.security.SecurityMiddleware', 

82 'whitenoise.middleware.WhiteNoiseMiddleware', 

83 'django.contrib.sessions.middleware.SessionMiddleware', 

84 'django.middleware.common.CommonMiddleware', 

85 'django.middleware.csrf.CsrfViewMiddleware', 

86 'django.contrib.auth.middleware.AuthenticationMiddleware', 

87 'django.contrib.messages.middleware.MessageMiddleware', 

88 'django.middleware.clickjacking.XFrameOptionsMiddleware', 

89] 

90 

91ROOT_URLCONF = 'src.urls' 

92 

93TEMPLATES = [ 

94 { 

95 'BACKEND': 'django.template.backends.django.DjangoTemplates', 

96 'DIRS': [BASE_DIR / 'templates'], 

97 'APP_DIRS': True, 

98 'OPTIONS': { 

99 'context_processors': [ 

100 'django.template.context_processors.request', 

101 'django.contrib.auth.context_processors.auth', 

102 'django.contrib.messages.context_processors.messages', 

103 ], 

104 }, 

105 }, 

106] 

107 

108WSGI_APPLICATION = 'src.wsgi.application' 

109 

110AUTHENTICATION_BACKENDS = [ 

111 # Custom authentication backend 

112 'src.accounts.authentication.CustomAuthBackendBackend', 

113 'django.contrib.auth.backends.ModelBackend', 

114] 

115 

116DATABASES = { 

117 'default': { 

118 'ENGINE': 'django.db.backends.postgresql', 

119 'NAME': os.getenv('DB_NAME', config('DB_NAME')), 

120 'USER': os.getenv('DB_USER', config('DB_USER')), 

121 'PASSWORD': os.getenv('DB_PASS', config('DB_PASS')), 

122 'HOST': os.getenv('DB_HOST', config('DB_HOST')), 

123 'PORT': os.getenv('DB_PORT', config('DB_PORT')), 

124 } 

125} 

126 

127AUTH_PASSWORD_VALIDATORS = [ 

128 { 

129 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', 

130 }, 

131 { 

132 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', 

133 'OPTIONS': {'min_length': 6}, 

134 }, 

135 { 

136 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', 

137 }, 

138 { 

139 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', 

140 }, 

141 # Custom validators 

142 { 

143 'NAME': 'src.accounts.validators.password.DigitRequiredValidator', 

144 }, 

145 { 

146 'NAME': 'src.accounts.validators.password.UpperCaseLetterRequiredValidator', 

147 }, 

148 { 

149 'NAME': 'src.accounts.validators.password.LowerCaseLetterRequiredValidator', 

150 }, 

151 { 

152 'NAME': 'src.accounts.validators.password.NoWhiteSpacesRequiredValidator', 

153 }, 

154 { 

155 'NAME': 'src.accounts.validators.password.SpecialCharRequiredValidator', 

156 }, 

157] 

158 

159AUTH_USER_MODEL = 'accounts.UserCredential' 

160 

161PASSWORD_RESET_TIMEOUT = 3600 

162 

163LANGUAGE_CODE = 'en-us' 

164TIME_ZONE = 'UTC' 

165USE_I18N = True 

166USE_TZ = True 

167 

168STATIC_URL = 'static/' 

169STATIC_ROOT = BASE_DIR / 'staticfiles' 

170 

171STATICFILES_DIRS = [ 

172 BASE_DIR / 'static', 

173] 

174 

175STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.StaticFilesStorage' 

176 

177STORAGES = { 

178 "default": { 

179 "BACKEND": "cloudinary_storage.storage.MediaCloudinaryStorage", 

180 }, 

181 "staticfiles": { 

182 "BACKEND": "django.contrib.staticfiles.storage.StaticFilesStorage", 

183 }, 

184} 

185 

186MEDIA_URL = 'media/' 

187MEDIA_ROOT = BASE_DIR / 'mediafiles/' 

188 

189DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' 

190 

191cloudinary.config( 

192 cloud_name=os.getenv('CLOUD_NAME', config('CLOUD_NAME')), 

193 api_key=os.getenv('CLOUD_API_KEY', config('CLOUD_API_KEY')), 

194 api_secret=os.getenv('CLOUD_API_SECRET', config('CLOUD_API_SECRET')), 

195) 

196 

197CELERY_BROKER_URL = os.getenv('CELERY_BROKER_URL', config('CELERY_BROKER_URL')) 

198CELERY_RESULT_BACKEND = os.getenv( 

199 'CELERY_RESULT_BACKEND', config('CELERY_RESULT_BACKEND') 

200) 

201CELERY_ACCEPT_CONTENT = ['application/json'] 

202CELERY_TASK_SERIALIZER = 'json' 

203CELERY_RESULT_SERIALIZER = 'json' 

204CELERY_TIMEZONE = TIME_ZONE 

205CELERY_BEAT_SCHEDULER = 'django_celery_beat.schedulers:DatabaseScheduler' 

206CELERY_BROKER_POOL_LIMIT = 2 

207CELERY_RESULT_BACKEND_CONNECTION_RETRY_ON_STARTUP = True 

208 

209EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' 

210EMAIL_HOST = 'smtp.gmail.com' 

211EMAIL_PORT = 587 

212EMAIL_USE_TLS = True 

213EMAIL_USE_SSL = False 

214EMAIL_HOST_PASSWORD = os.getenv( 

215 'EMAIL_HOST_PASSWORD', config('EMAIL_HOST_PASSWORD') 

216) 

217EMAIL_HOST_USER = 'djangogems@gmail.com' 

218DEFAULT_FROM_EMAIL = 'djangogems@gmail.com' 

219SERVER_EMAIL = 'djangogems@gmail.com' 

220 

221sentry_sdk.init( 

222 dsn=os.getenv('SENTRY_DSN', config('SENTRY_DSN')), 

223 send_default_pii=True, 

224) 

225 

226FRONTEND_URL = os.getenv( 

227 'CORS_ALLOWED_ORIGINS', config('CORS_ALLOWED_ORIGINS') 

228).split(',')[1]