diff --git a/Achievement_Inputing/settings.py b/Achievement_Inputing/settings.py index 77b2626..4d421fc 100644 --- a/Achievement_Inputing/settings.py +++ b/Achievement_Inputing/settings.py @@ -22,12 +22,12 @@ BASE_DIR = Path(__file__).resolve().parent.parent # 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-p^*6tak7wy1z#bw__#o^s5hsydearm=(-s(km!-61j2(#)*+-t' +SECRET_KEY = os.environ.get('DJANGO_SECRET_KEY', 'django-insecure-p^*6tak7wy1z#bw__#o^s5hsydearm=(-s(km!-61j2(#)*+-t') # SECURITY WARNING: don't run with debug turned on in production! -DEBUG = True +DEBUG = os.environ.get('DJANGO_DEBUG', 'True').lower() == 'true' -ALLOWED_HOSTS = ["127.0.0.1", "localhost"] +ALLOWED_HOSTS = os.environ.get('DJANGO_ALLOWED_HOSTS', '127.0.0.1,localhost').split(',') # Application definition @@ -47,6 +47,7 @@ INSTALLED_APPS = [ MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', + 'whitenoise.middleware.WhiteNoiseMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', @@ -121,6 +122,7 @@ USE_TZ = True # https://docs.djangoproject.com/en/5.2/howto/static-files/ STATIC_URL = 'static/' +STATIC_ROOT = BASE_DIR / 'staticfiles' # Media files (uploaded images) MEDIA_URL = '/media/' @@ -134,6 +136,8 @@ SESSION_COOKIE_SECURE = False if DEBUG else True CSRF_COOKIE_SECURE = False if DEBUG else True CSRF_COOKIE_SAMESITE = 'Lax' +CSRF_TRUSTED_ORIGINS = os.environ.get('DJANGO_CSRF_TRUSTED_ORIGINS', '').split(',') if os.environ.get('DJANGO_CSRF_TRUSTED_ORIGINS') else [] + X_FRAME_OPTIONS = 'DENY' # Default primary key field type @@ -142,9 +146,12 @@ X_FRAME_OPTIONS = 'DENY' DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' # Elasticsearch configuration +_ES_URL = os.environ.get('ELASTICSEARCH_URL', 'http://localhost:9200') +if not (_ES_URL.startswith('http://') or _ES_URL.startswith('https://')): + _ES_URL = 'http://' + _ES_URL ELASTICSEARCH_DSL = { 'default': { - 'hosts': 'localhost:9200' + 'hosts': _ES_URL }, } diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..afd8d8c --- /dev/null +++ b/Dockerfile @@ -0,0 +1,21 @@ +FROM python:3.11-slim + +ENV PYTHONDONTWRITEBYTECODE=1 \ + PYTHONUNBUFFERED=1 + +WORKDIR /app + +RUN apt-get update && apt-get install -y --no-install-recommends \ + build-essential \ + libjpeg62-turbo-dev \ + zlib1g-dev \ + && rm -rf /var/lib/apt/lists/* + +COPY requirements.txt /app/ +RUN pip install --no-cache-dir -r requirements.txt + +COPY . /app + +EXPOSE 8000 + +CMD ["sh","-c","python manage.py migrate && python manage.py collectstatic --noinput && gunicorn Achievement_Inputing.wsgi:application --bind 0.0.0.0:8000 --workers 3"] \ No newline at end of file diff --git a/accounts/views.py b/accounts/views.py index a1dc9b1..ebc35ff 100644 --- a/accounts/views.py +++ b/accounts/views.py @@ -6,7 +6,7 @@ import hmac from django.http import JsonResponse, HttpResponseBadRequest from django.shortcuts import render, redirect from django.views.decorators.http import require_http_methods -from django.views.decorators.csrf import csrf_protect +from django.views.decorators.csrf import csrf_protect, ensure_csrf_cookie from django.conf import settings from .es_client import get_user_by_username @@ -14,6 +14,7 @@ from .crypto import salt_for_username, hmac_sha256 @require_http_methods(["GET"]) +@ensure_csrf_cookie def login_page(request): return render(request, "accounts/login.html") diff --git a/elastic/es_connect.py b/elastic/es_connect.py index e1629b5..a8fce2c 100644 --- a/elastic/es_connect.py +++ b/elastic/es_connect.py @@ -4,6 +4,7 @@ Django版本的ES连接和操作模块 """ from elasticsearch import Elasticsearch from elasticsearch_dsl import connections +import os from .documents import AchievementDocument, UserDocument, GlobalDocument from .indexes import ACHIEVEMENT_INDEX_NAME, USER_INDEX_NAME, GLOBAL_INDEX_NAME import hashlib @@ -11,8 +12,11 @@ import time from datetime import datetime, timezone, timedelta import threading -# 使用Django的ES连接配置 -connections.create_connection(hosts=['localhost:9200']) +# 使用环境变量配置ES连接,默认为本机 +_ES_URL = os.environ.get('ELASTICSEARCH_URL', 'http://localhost:9200') +if not (_ES_URL.startswith('http://') or _ES_URL.startswith('https://')): + _ES_URL = 'http://' + _ES_URL +connections.create_connection(hosts=[_ES_URL]) # 获取默认的ES客户端 es = connections.get_connection() diff --git a/requirements.txt b/requirements.txt index 7aa9ef5..efd6d56 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,12 @@ +--index-url https://pypi.tuna.tsinghua.edu.cn/simple +--extra-index-url https://pypi.org/simple Django==5.2.8 -elasticsearch==8.17.1 -django-elasticsearch-dsl==7.3.0 +elasticsearch==7.17.9 +django-elasticsearch-dsl==7.4.0 +django-elasticsearch-dsl-drf==0.22 +elasticsearch-dsl==7.4.1 requests==2.32.3 openai==1.52.2 Pillow==10.4.0 +gunicorn==21.2.0 +whitenoise==6.6.0