Add a complete contact form system with the following changes: - Create ContactMessage model to store form submissions with tracking fields (is_read, is_responded) - Implement ContactMessage admin interface with custom actions, filters, and bulk operations - Add contact endpoint documentation to API root view - Update email configuration to use admin@attunehearttherapy.com as sender address This enables users to submit contact inquiries and allows administrators to track and manage these messages efficiently through the Django admin panel.
208 lines
5.3 KiB
Python
208 lines
5.3 KiB
Python
import os
|
|
from pathlib import Path
|
|
from datetime import timedelta
|
|
from dotenv import load_dotenv
|
|
import dj_database_url
|
|
|
|
load_dotenv()
|
|
|
|
BASE_DIR = Path(__file__).resolve().parent.parent
|
|
|
|
SECRET_KEY = os.getenv('JWT_SECRET', 'django-insecure-fallback-secret-key')
|
|
|
|
DEBUG = os.getenv('DEBUG', 'False').lower() == 'true'
|
|
|
|
ALLOWED_HOSTS = os.getenv('ALLOWED_HOSTS', '*').split(',')
|
|
|
|
# CORS Configuration
|
|
CORS_ALLOWED_ORIGINS = [
|
|
'https://attunehearttherapy.com'
|
|
]
|
|
|
|
CORS_ALLOW_CREDENTIALS = True
|
|
|
|
CSRF_TRUSTED_ORIGINS = [
|
|
'https://api.attunehearttherapy.com',
|
|
'https://attunehearttherapy.com'
|
|
]
|
|
|
|
INSTALLED_APPS = [
|
|
'jazzmin',
|
|
'django.contrib.admin',
|
|
'django.contrib.auth',
|
|
'django.contrib.contenttypes',
|
|
'django.contrib.sessions',
|
|
'django.contrib.messages',
|
|
'django.contrib.staticfiles',
|
|
|
|
'rest_framework',
|
|
'rest_framework_simplejwt',
|
|
'corsheaders',
|
|
'drf_spectacular',
|
|
|
|
'users',
|
|
'meetings',
|
|
]
|
|
|
|
MIDDLEWARE = [
|
|
'corsheaders.middleware.CorsMiddleware',
|
|
'django.middleware.security.SecurityMiddleware',
|
|
'whitenoise.middleware.WhiteNoiseMiddleware',
|
|
'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',
|
|
]
|
|
|
|
SITE_NAME = os.getenv('SITE_NAME', 'Attune Heart Therapy')
|
|
|
|
ROOT_URLCONF = 'booking_system.urls'
|
|
|
|
TEMPLATES = [
|
|
{
|
|
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
|
'DIRS': [
|
|
os.path.join(BASE_DIR, 'templates'),
|
|
],
|
|
'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 = 'booking_system.wsgi.application'
|
|
|
|
if not DEBUG:
|
|
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
|
|
|
|
|
|
if os.getenv('DATABASE_URL'):
|
|
DATABASES = {
|
|
'default': dj_database_url.config(
|
|
default=os.getenv('DATABASE_URL'),
|
|
conn_max_age=600,
|
|
conn_health_checks=True,
|
|
)
|
|
}
|
|
else:
|
|
DATABASES = {
|
|
'default': {
|
|
'ENGINE': 'django.db.backends.sqlite3',
|
|
'NAME': BASE_DIR / 'db.sqlite3',
|
|
}
|
|
}
|
|
|
|
ENCRYPTION_KEY = os.getenv('ENCRYPTION_KEY')
|
|
|
|
|
|
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',
|
|
},
|
|
]
|
|
|
|
|
|
SIMPLE_JWT = {
|
|
'ACCESS_TOKEN_LIFETIME': timedelta(hours=24),
|
|
'REFRESH_TOKEN_LIFETIME': timedelta(days=7),
|
|
'ROTATE_REFRESH_TOKENS': True,
|
|
'BLACKLIST_AFTER_ROTATION': True,
|
|
'SIGNING_KEY': os.getenv('JWT_SECRET', SECRET_KEY),
|
|
'AUTH_HEADER_TYPES': ('Bearer',),
|
|
}
|
|
|
|
STRIPE_PUBLISHABLE_KEY = os.getenv('STRIPE_PUBLISHABLE_KEY')
|
|
STRIPE_SECRET_KEY = os.getenv('STRIPE_SECRET_KEY')
|
|
STRIPE_WEBHOOK_SECRET = os.getenv('STRIPE_WEBHOOK_SECRET')
|
|
|
|
|
|
JITSI_BASE_URL = os.getenv('JITSI_BASE_URL', 'https://meet.jit.si')
|
|
|
|
|
|
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
|
|
EMAIL_HOST = os.getenv('SMTP_HOST', 'smtp.hostinger.com')
|
|
EMAIL_PORT = int(os.getenv('SMTP_PORT', 465))
|
|
EMAIL_USE_SSL = True
|
|
EMAIL_HOST_USER = os.getenv('SMTP_USERNAME', 'admin@attunehearttherapy.com')
|
|
EMAIL_HOST_PASSWORD = os.getenv('SMTP_PASSWORD')
|
|
DEFAULT_FROM_EMAIL = os.getenv('SMTP_FROM', 'admin@attunehearttherapy.com')
|
|
|
|
|
|
REST_FRAMEWORK = {
|
|
'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema',
|
|
'DEFAULT_AUTHENTICATION_CLASSES': (
|
|
'rest_framework_simplejwt.authentication.JWTAuthentication',
|
|
),
|
|
'DEFAULT_PERMISSION_CLASSES': (
|
|
'rest_framework.permissions.IsAuthenticated',
|
|
),
|
|
'DEFAULT_RENDERER_CLASSES': (
|
|
'rest_framework.renderers.JSONRenderer',
|
|
),
|
|
}
|
|
|
|
|
|
SPECTACULAR_SETTINGS = {
|
|
'TITLE': 'Attune Heart Therapy API',
|
|
'DESCRIPTION': 'API for managing appointments, meetings, and user authentication.',
|
|
'VERSION': '1.0.0',
|
|
'SERVE_INCLUDE_SCHEMA': False,
|
|
}
|
|
|
|
|
|
AUTH_USER_MODEL = 'users.CustomUser'
|
|
|
|
AUTHENTICATION_BACKENDS = [
|
|
'users.backends.EmailBackend',
|
|
'django.contrib.auth.backends.ModelBackend',
|
|
]
|
|
|
|
LANGUAGE_CODE = 'en-us'
|
|
TIME_ZONE = 'UTC'
|
|
USE_I18N = True
|
|
USE_TZ = True
|
|
|
|
|
|
STATIC_URL = '/static/'
|
|
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
|
|
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
|
|
|
|
|
|
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
|
|
|
|
|
|
CELERY_BROKER_URL = os.getenv('REDIS_URL', 'redis://localhost:6379/0')
|
|
CELERY_RESULT_BACKEND = os.getenv('REDIS_URL', 'redis://localhost:6379/0')
|
|
CELERY_ACCEPT_CONTENT = ['json']
|
|
CELERY_TASK_SERIALIZER = 'json'
|
|
|
|
|
|
LOGGING = {
|
|
'version': 1,
|
|
'disable_existing_loggers': False,
|
|
'handlers': {
|
|
'console': {
|
|
'class': 'logging.StreamHandler',
|
|
},
|
|
},
|
|
'root': {
|
|
'handlers': ['console'],
|
|
'level': 'INFO',
|
|
},
|
|
} |