Coverage for src/settings.py: 100%
63 statements
« prev ^ index » next coverage.py v7.9.2, created at 2025-08-04 12:59 +0300
« 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
5from django.utils.translation import gettext_lazy as _
6from decouple import config
8import cloudinary
9import cloudinary.uploader
10import cloudinary.api
12import sentry_sdk
14from .unfold import UNFOLD
16BASE_DIR = Path(__file__).resolve().parent.parent
18SECRET_KEY = os.getenv('SECRET_KEY', config('SECRET_KEY'))
20DEBUG = os.getenv('DEBUG', config('DEBUG')) == 'True'
22ALLOWED_HOSTS = os.getenv('ALLOWED_HOSTS', config('ALLOWED_HOSTS')).split(',')
24CSRF_TRUSTED_ORIGINS = os.getenv(
25 'CSRF_TRUSTED_ORIGINS', config('CSRF_TRUSTED_ORIGINS', [])
26).split(',')
28CORS_ALLOWED_ORIGINS = os.getenv(
29 'CORS_ALLOWED_ORIGINS', config('CORS_ALLOWED_ORIGINS')
30).split(',')
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]
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
63ASGI_APPLICATION = 'src.asgi.application'
65REST_FRAMEWORK = {
66 'DEFAULT_AUTHENTICATION_CLASSES': [
67 'rest_framework_simplejwt.authentication.JWTAuthentication',
68 ],
69 'DEFAULT_PERMISSION_CLASSES': [
70 'rest_framework.permissions.IsAuthenticated',
71 ],
72}
74SIMPLE_JWT = {
75 'ACCESS_TOKEN_LIFETIME': timedelta(minutes=15),
76 'REFRESH_TOKEN_LIFETIME': timedelta(days=7),
77}
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]
91ROOT_URLCONF = 'src.urls'
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]
108WSGI_APPLICATION = 'src.wsgi.application'
110AUTHENTICATION_BACKENDS = [
111 # Custom authentication backend
112 'src.accounts.authentication.CustomAuthBackendBackend',
113 'django.contrib.auth.backends.ModelBackend',
114]
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}
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]
159AUTH_USER_MODEL = 'accounts.UserCredential'
161PASSWORD_RESET_TIMEOUT = 3600
163LANGUAGE_CODE = 'en-us'
164TIME_ZONE = 'UTC'
165USE_I18N = True
166USE_TZ = True
168STATIC_URL = 'static/'
169STATIC_ROOT = BASE_DIR / 'staticfiles'
171STATICFILES_DIRS = [
172 BASE_DIR / 'static',
173]
175STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.StaticFilesStorage'
177STORAGES = {
178 "default": {
179 "BACKEND": "cloudinary_storage.storage.MediaCloudinaryStorage",
180 },
181 "staticfiles": {
182 "BACKEND": "django.contrib.staticfiles.storage.StaticFilesStorage",
183 },
184}
186MEDIA_URL = 'media/'
187MEDIA_ROOT = BASE_DIR / 'mediafiles/'
189DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
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)
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
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'
221sentry_sdk.init(
222 dsn=os.getenv('SENTRY_DSN', config('SENTRY_DSN')),
223 send_default_pii=True,
224)
226FRONTEND_URL = os.getenv(
227 'CORS_ALLOWED_ORIGINS', config('CORS_ALLOWED_ORIGINS')
228).split(',')[1]