diff --git a/.dockerignore b/.dockerignore index e69de29..f5e96db 100644 --- a/.dockerignore +++ b/.dockerignore @@ -0,0 +1 @@ +venv \ No newline at end of file diff --git a/config/celery.py b/config/celery.py index e69de29..2667b4b 100644 --- a/config/celery.py +++ b/config/celery.py @@ -0,0 +1,11 @@ +import os + +from celery import Celery + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings.base') + +app = Celery('config') + +app.config_from_object('django.conf:settings', namespace='CELERY') + +app.autodiscover_tasks() diff --git a/config/conf/__init__.py b/config/conf/__init__.py index e69de29..27fe4f1 100644 --- a/config/conf/__init__.py +++ b/config/conf/__init__.py @@ -0,0 +1,5 @@ +from .jazzmin import * +from .drf_yasg import * +from .redis import * +from .rest_framework import * +from .rest_framework_simplejwt import * \ No newline at end of file diff --git a/config/conf/jazzmin.py b/config/conf/jazzmin.py new file mode 100644 index 0000000..5903705 --- /dev/null +++ b/config/conf/jazzmin.py @@ -0,0 +1,55 @@ +JAZZMIN_SETTINGS = { + "site_title": "UyQur Admin", + "site_header": "UyQur", + "site_brand": "UyQur", + "site_logo": None, + "login_logo": None, + "login_logo_dark": None, + "site_logo_classes": "img-circle", + "site_icon": None, + "welcome_sign": "Welcome to the UyQur", + "copyright": "Acme UyQur Ltd", + + "search_model": ["auth.User"], + "user_avatar": None, + "topmenu_links": [ + {"name": "Home", "url": "admin:index", "permissions": ["auth.view_user"]}, + {"model": "auth.User"}, + ], + + "usermenu_links": [ + {"name": "Support", "url": "https://github.com/farridav/django-jazzmin/issues", "new_window": True}, + {"model": "auth.user"} + ], + + "show_sidebar": True, + "navigation_expanded": True, + "hide_apps": [], + "hide_models": ["auth.Group"], + "order_with_respect_to": ["auth"], + + "custom_links": { + "books": [{ + "name": "Make Messages", + "url": "make_messages", + "icon": "fas fa-comments", + "permissions": ["books.view_book"] + }] + }, + + "icons": { + "auth": "fas fa-users-cog", + "auth.user": "fas fa-user", + }, + + "default_icon_parents": "fas fa-chevron-circle-right", + "default_icon_children": "fas fa-circle", + + "related_modal_active": True, + + "use_google_fonts_cdn": True, + "show_ui_builder": False, + + "changeform_format": "collapsible", + "language_chooser": False, +} \ No newline at end of file diff --git a/config/conf/logs.py b/config/conf/logs.py new file mode 100644 index 0000000..04be32d --- /dev/null +++ b/config/conf/logs.py @@ -0,0 +1,41 @@ +LOGGING = { + "version": 1, + "disable_existing_loggers": False, + "formatters": { + "verbose": { + "format": "{levelname} {asctime} {module} {message}", + "style": "{", + }, + }, + "handlers": { + "daily_rotating_file": { + "level": "INFO", + "class": "logging.handlers.TimedRotatingFileHandler", + "filename": "resources/logs/django.log", + "when": "midnight", + "backupCount": 30, + "formatter": "verbose", + }, + "daily_rotating_file_error_log": { + "level": "INFO", + "class": "logging.handlers.TimedRotatingFileHandler", + "filename": "resources/logs/error.log", + "when": "midnight", + "backupCount": 30, + "formatter": "verbose", + }, + + }, + "loggers": { + "django": { + "handlers": ["daily_rotating_file"], + "level": "INFO", + "propagate": True, + }, + "error": { + "handlers": ['daily_rotating_file_error_log'], + "level": "ERROR", + "propagate": True, + } + }, +} \ No newline at end of file diff --git a/config/conf/redis.py b/config/conf/redis.py new file mode 100644 index 0000000..9242bbc --- /dev/null +++ b/config/conf/redis.py @@ -0,0 +1,24 @@ +CACHES = { + "default": { + "BACKEND": 'django_redis.cache.RedisCache', + "LOCATION": 'redis://127.0.0.1:6379/1', + "TIMEOUT": 5, + }, +} + +CACHE_MIDDLEWARE_SECONDS = 5 + + +CACHEOPS_REDIS = 'redis://127.0.0.1:6379/1' +CACHEOPS_DEFAULTS = { + "timeout": 5, +} + +CACHEOPS = { + "accounts.*": { + "ops": "all", + "timeout": 60 * 5, + }, +} +CACHEOPS_DEGRADE_ON_FAILURE = True +CACHEOPS_ENABLED = False \ No newline at end of file diff --git a/config/conf/rest_framework.py b/config/conf/rest_framework.py new file mode 100644 index 0000000..2c5ed1b --- /dev/null +++ b/config/conf/rest_framework.py @@ -0,0 +1,7 @@ +REST_FRAMEWORK = { + "DEFAULT_AUTHENTICATION_CLASSES": [ + 'rest_framework.authentication.SessionAuthentication', + 'rest_framework.authentication.BasicAuthentication' + 'rest_framework_simplejwt.authentication.JWTAuthentication', + ] +} \ No newline at end of file diff --git a/config/conf/rest_framework_simplejwt.py b/config/conf/rest_framework_simplejwt.py new file mode 100644 index 0000000..d5e3cd9 --- /dev/null +++ b/config/conf/rest_framework_simplejwt.py @@ -0,0 +1,10 @@ +from datetime import timedelta + + +SIMPLE_JWT = { + "ACCESS_TOKEN_LIFETIME": timedelta(days=1), + "REFRESH_TOKEN_LIFETIME": timedelta(days=30), + "ROTATE_REFRESH_TOKENS": True, + "BLACKLIST_AFTER_ROTATION": True, + "UPDATE_LAST_LOGIN": True, +} \ No newline at end of file diff --git a/config/settings/base.py b/config/settings/base.py index 09a47d8..21d101f 100644 --- a/config/settings/base.py +++ b/config/settings/base.py @@ -26,9 +26,12 @@ APPS = [ PACKAGES = [ 'drf_yasg', + 'rest_framework', + 'rest_framework_simplejwt', ] DJANGO_APPS = [ + 'jazzmin', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', @@ -132,3 +135,6 @@ MEDIA_ROOT = BASE_DIR / 'resources/media' # https://docs.djangoproject.com/en/5.2/ref/settings/#default-auto-field DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' + + +from config.conf import * diff --git a/requirements.txt b/requirements.txt index 9c276b5..dec505c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,16 +1,15 @@ -asgiref==3.9.1 +celery==5.5.3 click==8.2.1 Django==5.2.4 +django-cacheops==7.2 django-environ==0.12.0 +django-jazzmin==3.0.1 +django-redis==6.0.0 djangorestframework==3.16.0 +djangorestframework_simplejwt==5.5.1 drf-yasg==1.21.10 gunicorn==23.0.0 -h11==0.16.0 -inflection==0.5.1 -packaging==25.0 psycopg2-binary==2.9.10 -pytz==2025.2 -PyYAML==6.0.2 -sqlparse==0.5.3 -uritemplate==4.2.0 +redis==6.2.0 uvicorn==0.35.0 +pillow \ No newline at end of file