2025-04-29 15:43:53 +03:30
"""
Django settings for Rasaddam_Backend project .
Generated by ' django-admin startproject ' using Django 5.2 .
For more information on this file , see
https : / / docs . djangoproject . com / en / 5.2 / topics / settings /
For the full list of settings and their values , see
https : / / docs . djangoproject . com / en / 5.2 / ref / settings /
"""
2025-05-04 15:24:28 +03:30
import os . path
from datetime import timedelta
2025-05-24 15:01:55 +03:30
from pathlib import Path
2025-07-02 15:42:51 +03:30
import sentry_sdk
2025-05-24 15:01:55 +03:30
2025-05-04 15:24:28 +03:30
from django . conf import settings
2025-05-04 15:40:55 +03:30
2025-04-29 15:43:53 +03:30
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path ( __file__ ) . resolve ( ) . parent . parent
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/5.2/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = ' django-insecure-@0apn-lk85pfw=z00x2ib$w9#rwz8 % 2v4i_n^^9jz-m9b+y55* '
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
2025-07-02 15:42:51 +03:30
sentry_sdk . init (
dsn = " https://e8d8ff4f1bf729370af00b7775be441c@o4509597964697600.ingest.us.sentry.io/4509597966073856 " ,
# Add data like request headers and IP for users,
# see https://docs.sentry.io/platforms/python/data-management/data-collected/ for more info
send_default_pii = True ,
# Set traces_sample_rate to 1.0 to capture 100%
# of transactions for tracing.
traces_sample_rate = 1.0 ,
# Set profile_session_sample_rate to 1.0 to profile 100%
# of profile sessions.
profile_session_sample_rate = 1.0 ,
# Set profile_lifecycle to "trace" to automatically
# run the profiler on when there is an active transaction
profile_lifecycle = " trace " ,
)
2025-07-19 14:33:18 +03:30
ASGI_APPLICATION = " Rasaddam_Backend.asgi.application " # noqa
2025-05-24 16:26:28 +03:30
ALLOWED_HOSTS = [
' localhost ' ,
' 127.0.0.1 ' ,
' https://rasadyar.net/ ' ,
' https://localhost:9200 ' ,
2025-05-24 16:59:30 +03:30
' https://api.rasadyaar.net ' ,
2025-05-24 17:04:18 +03:30
' https://api.dam.rasadyaar.net ' ,
2025-05-31 16:47:29 +03:30
' https://dam.rasadyar.net '
2025-05-24 16:26:28 +03:30
' http://localhost:3000 ' ,
2025-05-27 15:09:22 +03:30
' http://192.168.88.130:3000 ' ,
' https://rasaddam-front.liara.run '
2025-05-24 16:26:28 +03:30
]
2025-04-29 15:43:53 +03:30
# Application definition
INSTALLED_APPS = [
2025-07-24 16:02:08 +03:30
' jazzmin ' , # noqa
2025-04-29 15:43:53 +03:30
' django.contrib.admin ' ,
' django.contrib.auth ' ,
' django.contrib.contenttypes ' ,
' django.contrib.sessions ' ,
' django.contrib.messages ' ,
' django.contrib.staticfiles ' ,
2025-05-06 16:22:35 +03:30
' django_elasticsearch_dsl ' ,
' django_elasticsearch_dsl_drf ' ,
2025-04-30 15:03:40 +03:30
' rest_framework ' ,
2025-04-30 10:29:37 +03:30
" corsheaders " ,
2025-05-04 15:24:28 +03:30
' rest_framework_simplejwt ' ,
2025-05-24 15:01:55 +03:30
' rest_framework_simplejwt.token_blacklist ' ,
2025-04-30 15:03:40 +03:30
' apps.authentication.apps.AuthenticationConfig ' ,
' apps.authorization.apps.AuthorizationConfig ' ,
2025-05-05 15:25:46 +03:30
' apps.captcha_app.apps.CaptchaAppConfig ' ,
' apps.core.apps.CoreConfig ' ,
' apps.herd.apps.HerdAppConfig ' ,
' apps.livestock.apps.LivestockConfig ' ,
2025-07-16 12:21:29 +03:30
' apps.pos_device.apps.PosDeviceConfig ' ,
2025-05-05 15:25:46 +03:30
' apps.tag.apps.TagConfig ' ,
' apps.warehouse.apps.WarehouseConfig ' ,
2025-05-06 16:22:35 +03:30
' apps.search.apps.SearchConfig ' ,
2025-05-24 15:01:55 +03:30
' apps.log.apps.LogConfig ' ,
2025-06-07 09:18:27 +03:30
' apps.product.apps.ProductConfig ' ,
2025-05-04 15:24:28 +03:30
' rest_captcha ' ,
' captcha ' ,
2025-07-19 10:41:03 +03:30
' drf_yasg ' ,
" django_celery_results " ,
" django_celery_beat " ,
2025-07-24 16:02:08 +03:30
2025-04-29 15:43:53 +03:30
]
MIDDLEWARE = [
2025-05-24 17:08:47 +03:30
" corsheaders.middleware.CorsMiddleware " ,
2025-04-29 15:43:53 +03:30
' django.middleware.security.SecurityMiddleware ' ,
' django.contrib.sessions.middleware.SessionMiddleware ' ,
' django.middleware.common.CommonMiddleware ' ,
' django.middleware.csrf.CsrfViewMiddleware ' ,
' django.contrib.auth.middleware.AuthenticationMiddleware ' ,
' django.contrib.messages.middleware.MessageMiddleware ' ,
' django.middleware.clickjacking.XFrameOptionsMiddleware ' ,
2025-06-02 12:18:13 +03:30
' apps.authentication.middlewares.BlockedTokenMiddleware ' ,
2025-05-24 15:01:55 +03:30
' crum.CurrentRequestUserMiddleware ' ,
' apps.log.middlewares.SaveLog '
2025-04-29 15:43:53 +03:30
]
ROOT_URLCONF = ' Rasaddam_Backend.urls '
TEMPLATES = [
{
' BACKEND ' : ' django.template.backends.django.DjangoTemplates ' ,
' DIRS ' : [ ] ,
' APP_DIRS ' : True ,
' OPTIONS ' : {
' context_processors ' : [
' django.template.context_processors.request ' ,
' django.contrib.auth.context_processors.auth ' ,
' django.contrib.messages.context_processors.messages ' ,
] ,
} ,
} ,
]
WSGI_APPLICATION = ' Rasaddam_Backend.wsgi.application '
# Database
# https://docs.djangoproject.com/en/5.2/ref/settings/#databases
2025-05-24 15:01:55 +03:30
MONGODB_DATABASES = {
" default " : {
" name " : ' mongodb ' ,
" host " : " " ,
" tz_aware " : True , # if you using timezones in django (USE_TZ = True) # noqa
} ,
}
2025-04-29 15:43:53 +03:30
DATABASES = {
' default ' : {
2025-04-30 09:40:46 +03:30
' ENGINE ' : ' django.db.backends.postgresql_psycopg2 ' ,
' NAME ' : " postgres " ,
' HOST ' : " monte-rosa.liara.cloud " ,
' USER ' : " root " ,
' PASSWORD ' : " aFC3hqbxxR0SeBPZ6TCZ37my " ,
' PORT ' : ' 32718 '
2025-05-24 15:01:55 +03:30
} ,
2025-04-29 15:43:53 +03:30
}
2025-04-30 15:03:40 +03:30
AUTH_USER_MODEL = ' authentication.User '
2025-05-24 15:01:55 +03:30
SWAGGER_SETTINGS = {
' SECURITY_DEFINITIONS ' : {
2025-07-02 15:42:51 +03:30
" bearer " : {
" type " : " apiKey " ,
" name " : " Authorization " ,
" in " : " header " ,
" description " : ' JWT Authorization header using the Bearer scheme. Example: " Authorization: Bearer <token> " ' ,
2025-05-24 15:01:55 +03:30
} ,
' basic ' : { # <<-- is for djagno authentication
' type ' : ' basic '
} ,
} ,
2025-07-02 15:42:51 +03:30
' USE_SESSION_AUTH ' : False ,
" DEFAULT_AUTO_SCHEMA_CLASS " : " drf_yasg.inspectors.SwaggerAutoSchema "
2025-05-24 15:01:55 +03:30
}
2025-07-19 10:41:03 +03:30
CELERY_BROKER_URL = " redis://:ydnW4hwzuDRYcTX3FWCHgQ1f@apo.liara.cloud:33740/0 " # Requires Redis server
accept_content = [ " application/json " ]
result_serializer = " json "
task_serializer = " json "
timezone = " UTC "
CELERY_RESULT_BACKEND = " redis://:ydnW4hwzuDRYcTX3FWCHgQ1f@apo.liara.cloud:33740/0 "
CELERY_CACHE_BACKEND = ' default '
# Celery Beat settings
CELERY_BEAT_SCHEDULER = " django_celery_beat.schedulers:DatabaseScheduler "
2025-05-24 15:01:55 +03:30
LOGIN_URL = ' rest_framework:login '
LOGOUT_URL = ' rest_framework:logout '
2025-04-30 15:03:40 +03:30
REST_FRAMEWORK = {
' DEFAULT_PERMISSION_CLASSES ' : (
' rest_framework.permissions.IsAuthenticated ' ,
) ,
' DEFAULT_AUTHENTICATION_CLASSES ' : (
2025-05-04 15:24:28 +03:30
' rest_framework_simplejwt.authentication.JWTAuthentication ' ,
2025-04-30 15:03:40 +03:30
' rest_framework.authentication.SessionAuthentication ' ,
' rest_framework.authentication.BasicAuthentication ' ,
) ,
2025-06-07 12:23:11 +03:30
' DEFAULT_FILTER_BACKENDS ' : [
' django_filters.rest_framework.DjangoFilterBackend ' ,
' rest_framework.filters.SearchFilter ' ,
] ,
2025-07-02 15:42:51 +03:30
# 'EXCEPTION_HANDLER': 'apps.core.error_handler.custom_exception_handler',
2025-06-07 09:18:27 +03:30
" DEFAULT_PAGINATION_CLASS " : ' apps.core.pagination.CustomPageNumberPagination ' ,
" PAGE_SIZE " : 20 ,
2025-05-24 15:01:55 +03:30
' DEFAULT_SCHEMA_CLASS ' : ' rest_framework.schemas.coreapi.AutoSchema '
2025-04-30 15:03:40 +03:30
}
2025-04-29 15:43:53 +03:30
2025-05-04 15:24:28 +03:30
SIMPLE_JWT = {
2025-05-05 15:25:46 +03:30
" ACCESS_TOKEN_LIFETIME " : timedelta ( days = 1 ) ,
2025-05-04 15:24:28 +03:30
" REFRESH_TOKEN_LIFETIME " : timedelta ( days = 1 ) ,
" ROTATE_REFRESH_TOKENS " : False ,
" BLACKLIST_AFTER_ROTATION " : False ,
" UPDATE_LAST_LOGIN " : False ,
" ALGORITHM " : " HS256 " ,
2025-05-04 15:52:38 +03:30
" SIGNING_KEY " : ' django-insecure-@0apn-lk85pfw=z00x2ib$w9#rwz8 % 2v4i_n^^9jz-m9b+y55* ' ,
2025-05-04 15:24:28 +03:30
" VERIFYING_KEY " : " " ,
" AUDIENCE " : None ,
" ISSUER " : None ,
" JSON_ENCODER " : None ,
" JWK_URL " : None ,
" LEEWAY " : 0 ,
" AUTH_HEADER_TYPES " : ( " Bearer " , ) ,
" AUTH_HEADER_NAME " : " HTTP_AUTHORIZATION " ,
" USER_ID_FIELD " : " id " ,
" USER_ID_CLAIM " : " user_id " ,
" USER_AUTHENTICATION_RULE " : " rest_framework_simplejwt.authentication.default_user_authentication_rule " ,
" AUTH_TOKEN_CLASSES " : ( " rest_framework_simplejwt.tokens.AccessToken " , ) ,
" TOKEN_TYPE_CLAIM " : " token_type " ,
" TOKEN_USER_CLASS " : " rest_framework_simplejwt.models.TokenUser " ,
" JTI_CLAIM " : " jti " ,
" SLIDING_TOKEN_REFRESH_EXP_CLAIM " : " refresh_exp " ,
" SLIDING_TOKEN_LIFETIME " : timedelta ( minutes = 5 ) ,
" SLIDING_TOKEN_REFRESH_LIFETIME " : timedelta ( days = 1 ) ,
" TOKEN_OBTAIN_SERIALIZER " : ' apps.authentication.api.v1.jwt_serializer.CustomizedTokenObtainPairSerializer ' ,
" TOKEN_REFRESH_SERIALIZER " : " rest_framework_simplejwt.serializers.TokenRefreshSerializer " ,
" TOKEN_VERIFY_SERIALIZER " : " rest_framework_simplejwt.serializers.TokenVerifySerializer " ,
" TOKEN_BLACKLIST_SERIALIZER " : " rest_framework_simplejwt.serializers.TokenBlacklistSerializer " ,
" SLIDING_TOKEN_OBTAIN_SERIALIZER " : " rest_framework_simplejwt.serializers.TokenObtainSlidingSerializer " ,
" SLIDING_TOKEN_REFRESH_SERIALIZER " : " rest_framework_simplejwt.serializers.TokenRefreshSlidingSerializer " ,
}
CACHES = {
2025-05-04 16:11:07 +03:30
" default " : {
" BACKEND " : " django_redis.cache.RedisCache " ,
" LOCATION " : " redis://:ydnW4hwzuDRYcTX3FWCHgQ1f@apo.liara.cloud:33740/0 " ,
" OPTIONS " : {
" CLIENT_CLASS " : " django_redis.client.DefaultClient " ,
} ,
" KEY_PREFIX " : " You have successfully set up a key-value pair! "
2025-05-04 15:24:28 +03:30
} ,
' memcache ' : {
" BACKEND " : " django.core.cache.backends.memcached.PyMemcacheCache " ,
" LOCATION " : " 127.0.0.1:11211 " ,
}
}
2025-07-21 09:39:31 +03:30
CHANNEL_LAYERS = {
" default " : {
" BACKEND " : " channels_redis.core.RedisChannelLayer " ,
" CONFIG " : {
" hosts " : [ ( " redis://:ydnW4hwzuDRYcTX3FWCHgQ1f@apo.liara.cloud:33740/0 " ) ] ,
} ,
} ,
}
2025-05-04 15:24:28 +03:30
REST_CAPTCHA = {
' CAPTCHA_CACHE ' : ' default ' ,
' CAPTCHA_TIMEOUT ' : 300 , # 5 minutes
' CAPTCHA_LENGTH ' : 6 ,
' CAPTCHA_FONT_SIZE ' : 35 ,
' CAPTCHA_IMAGE_SIZE ' : ( 90 , 20 ) ,
' CAPTCHA_LETTER_ROTATION ' : ( - 35 , 35 ) ,
' CAPTCHA_FOREGROUND_COLOR ' : ' #000000 ' ,
' CAPTCHA_BACKGROUND_COLOR ' : ' #ffffff ' ,
2025-05-05 08:46:20 +03:30
# 'CAPTCHA_FONT_PATH':
2025-05-04 15:24:28 +03:30
' CAPTCHA_CACHE_KEY ' : ' rest_captcha_ {key} . {version} ' ,
' FILTER_FUNCTION ' : ' rest_captcha.captcha.filter_default ' ,
' NOISE_FUNCTION ' : ' apps.captcha_app.api.v1.serializers.noise_default '
}
2025-05-06 16:22:35 +03:30
ELASTICSEARCH_DSL = {
# elastic HSA256 finger print f7d94c1da0668ba7874e5e09c3b1b91284fcdda97c361e0165401dc9375531b0 # noqa
# liara elastic password uYkiQ860vLW8DIbWpNjqtz2B # noqa
# local system password =z66+LCIebq4NQRR_+=R # noqa
" default " : {
2025-05-24 15:01:55 +03:30
" hosts " : " http://monte-rosa.liara.cloud:31157 " ,
2025-05-06 16:22:35 +03:30
" http_auth " : ( " elastic " , " uYkiQ860vLW8DIbWpNjqtz2B " ) ,
}
}
2025-04-29 15:43:53 +03:30
# Password validation
# https://docs.djangoproject.com/en/5.2/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
' NAME ' : ' django.contrib.auth.password_validation.UserAttributeSimilarityValidator ' ,
} ,
{
' NAME ' : ' django.contrib.auth.password_validation.MinimumLengthValidator ' ,
} ,
{
' NAME ' : ' django.contrib.auth.password_validation.CommonPasswordValidator ' ,
} ,
{
' NAME ' : ' django.contrib.auth.password_validation.NumericPasswordValidator ' ,
} ,
]
# Internationalization
# https://docs.djangoproject.com/en/5.2/topics/i18n/
LANGUAGE_CODE = ' en-us '
TIME_ZONE = ' UTC '
USE_I18N = True
USE_TZ = True
2025-04-30 10:29:37 +03:30
DATETIME_FORMAT = ' % Y- % m- %d % H: % M: % S '
2025-04-29 15:43:53 +03:30
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/5.2/howto/static-files/
STATIC_URL = ' static/ '
# Default primary key field type
# https://docs.djangoproject.com/en/5.2/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = ' django.db.models.BigAutoField '
2025-04-30 10:29:37 +03:30
DATA_UPLOAD_MAX_MEMORY_SIZE = 50242880
2025-05-25 09:17:02 +03:30
CORS_ORIGIN_ALLOW_ALL = False
CORS_ALLOW_CREDENTIALS = True
2025-04-30 10:29:37 +03:30
2025-05-25 09:17:02 +03:30
CORS_ALLOWED_ORIGINS = (
' http://localhost:8080 ' ,
' http://127.0.0.1:8080 ' ,
' http://127.0.0.1:3000 ' ,
' http://localhost:3000 ' ,
' http://192.168.88.130:3000 ' ,
2025-05-27 15:38:40 +03:30
' https://rasadyar.net ' ,
2025-05-31 16:40:23 +03:30
' https://rasaddam-front.liara.run ' ,
2025-05-31 16:47:29 +03:30
' https://dam.rasadyar.net '
2025-05-25 09:17:02 +03:30
)
2025-04-30 10:29:37 +03:30
SECURE_PROXY_SSL_HEADER = ( ' HTTP_X_FORWARDED_PROTO ' , ' https ' )
SECURE_SSL_REDIRECT = False
SESSION_COOKIE_SECURE = False
CSRF_COOKIE_SECURE = False
2025-07-24 16:02:08 +03:30
JAZZMIN_SETTINGS = {
# title of the window (Will default to current_admin_site.site_title if absent or None)
" site_title " : " Library Admin " ,
# Title on the login screen (19 chars max) (defaults to current_admin_site.site_header if absent or None)
" site_header " : " Library " ,
# Title on the brand (19 chars max) (defaults to current_admin_site.site_header if absent or None)
" site_brand " : " Library " ,
# Logo to use for your site, must be present in static files, used for brand on top left
" site_logo " : " books/img/logo.png " ,
# Logo to use for your site, must be present in static files, used for login form logo (defaults to site_logo)
" login_logo " : None ,
# Logo to use for login form in dark themes (defaults to login_logo)
" login_logo_dark " : None ,
# CSS classes that are applied to the logo above
" site_logo_classes " : " img-circle " ,
# Relative path to a favicon for your site, will default to site_logo if absent (ideally 32x32 px)
" site_icon " : None ,
# Welcome text on the login screen
" welcome_sign " : " Welcome to the library " ,
# Copyright on the footer
" copyright " : " Acme Library Ltd " ,
# List of model admins to search from the search bar, search bar omitted if excluded
# If you want to use a single search field you dont need to use a list, you can use a simple string
" search_model " : [ " auth.User " , " auth.Group " ] ,
# Field name on user model that contains avatar ImageField/URLField/Charfield or a callable that receives the user
" user_avatar " : None ,
############
# Top Menu #
############
# Links to put along the top menu
" topmenu_links " : [
# Url that gets reversed (Permissions can be added)
{ " name " : " Home " , " url " : " admin:index " , " permissions " : [ " auth.view_user " ] } ,
# external url that opens in a new window (Permissions can be added)
{ " name " : " Support " , " url " : " https://github.com/farridav/django-jazzmin/issues " , " new_window " : True } ,
# model admin to link to (Permissions checked against model)
{ " model " : " auth.User " } ,
# App with dropdown menu to all its models pages (Permissions checked against models)
{ " app " : " books " } ,
] ,
#############
# User Menu #
#############
# Additional links to include in the user menu on the top right ("app" url type is not allowed)
" usermenu_links " : [
{ " name " : " Support " , " url " : " https://github.com/farridav/django-jazzmin/issues " , " new_window " : True } ,
{ " model " : " auth.user " }
] ,
#############
# Side Menu #
#############
# Whether to display the side menu
" show_sidebar " : True ,
# Whether to aut expand the menu
" navigation_expanded " : True ,
# Hide these apps when generating side menu e.g (auth)
" hide_apps " : [ ] ,
# Hide these models when generating side menu (e.g auth.user)
" hide_models " : [ ] ,
# List of apps (and/or models) to base side menu ordering off of (does not need to contain all apps/models)
" order_with_respect_to " : [ " auth " , " books " , " books.author " , " books.book " ] ,
# Custom links to append to app groups, keyed on app name
" custom_links " : {
" books " : [ {
" name " : " Make Messages " ,
" url " : " make_messages " ,
" icon " : " fas fa-comments " ,
" permissions " : [ " books.view_book " ]
} ]
} ,
# Custom icons for side menu apps/models See https://fontawesome.com/icons?d=gallery&m=free&v=5.0.0,5.0.1,5.0.10,5.0.11,5.0.12,5.0.13,5.0.2,5.0.3,5.0.4,5.0.5,5.0.6,5.0.7,5.0.8,5.0.9,5.1.0,5.1.1,5.2.0,5.3.0,5.3.1,5.4.0,5.4.1,5.4.2,5.13.0,5.12.0,5.11.2,5.11.1,5.10.0,5.9.0,5.8.2,5.8.1,5.7.2,5.7.1,5.7.0,5.6.3,5.5.0,5.4.2
# for the full list of 5.13.0 free icon classes
" icons " : {
" auth " : " fas fa-users-cog " ,
" auth.user " : " fas fa-user " ,
" auth.Group " : " fas fa-users " ,
} ,
# Icons that are used when one is not manually specified
" default_icon_parents " : " fas fa-chevron-circle-right " ,
" default_icon_children " : " fas fa-circle " ,
#################
# Related Modal #
#################
# Use modals instead of popups
" related_modal_active " : False ,
#############
# UI Tweaks #
#############
# Relative paths to custom CSS/JS scripts (must be present in static files)
" custom_css " : None ,
" custom_js " : None ,
# Whether to link font from fonts.googleapis.com (use custom_css to supply font otherwise)
" use_google_fonts_cdn " : True ,
# Whether to show the UI customizer on the sidebar
" show_ui_builder " : False ,
###############
# Change view #
###############
# Render out the change view as a single form, or in tabs, current options are
# - single
# - horizontal_tabs (default)
# - vertical_tabs
# - collapsible
# - carousel
" changeform_format " : " horizontal_tabs " ,
# override change forms on a per modeladmin basis
" changeform_format_overrides " : { " auth.user " : " collapsible " , " auth.group " : " vertical_tabs " } ,
# Add a language dropdown into the admin
# "language_chooser": True,
}