AWS Nginx部署Django遇改动不生效、样式失效、CSRF报错问题
问题1:Django代码修改后改动不生效
- 重启Gunicorn进程:生产环境下Gunicorn默认关闭代码热加载,多worker进程常驻内存不会自动读取新代码,若用systemd管理服务直接执行
sudo systemctl restart gunicorn,手动启动的场景先找到Gunicorn主进程kill后重新拉起,确保所有worker加载最新代码。 - 核对部署路径一致性:检查Gunicorn启动配置中指定的项目根目录(chdir参数)、wsgi入口文件路径,和你实际修改代码的目录完全匹配,避免修改了其他位置的代码,Gunicorn仍加载旧目录下的项目。
- 清除编译缓存:在项目根目录执行
find . -name "*.pyc" -delete,删除旧的Python字节码缓存文件,避免旧逻辑被优先加载。 - 排查缓存配置影响:如果开启了视图缓存、模板全页缓存,临时注释对应缓存配置后重启服务验证,排除缓存返回旧内容的干扰。
问题2:静态样式加载失败
你配置的STATIC_URL、STATIC_ROOT和urls静态路由仅满足配置前置要求,生产环境静态资源默认由Nginx处理,Django本身不对外服务静态文件,按以下步骤修复:
- 执行静态文件收集命令:在项目根目录运行
python manage.py collectstatic --noinput,将所有app内的静态资源、项目自定义静态文件全部归集到STATIC_ROOT指定的static目录下,未执行该命令时STATIC_ROOT目录为空,自然无法返回静态资源。
注意:urls.py中添加的
+ static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)规则仅在DEBUG=True模式下生效,生产环境DEBUG=False时该配置完全不生效,不能依赖Django本身处理静态请求。
- 添加Nginx静态资源规则:在Nginx的站点配置文件的server块中,新增静态路径匹配规则:
location /static/ { root /你的项目绝对路径; # 例:STATIC_ROOT为/opt/demo/static时,root填/opt/demo expires 30d; }
- 修正目录权限:执行
sudo chown -R nginx:nginx /你的项目路径/static(Amazon Linux系统默认Nginx运行用户为nginx,Ubuntu系统为www-data,替换对应用户即可),确保Nginx进程对static目录有读取和访问权限,避免返回403错误。 - 校验并重载Nginx:执行
sudo nginx -t确认配置语法无错后,运行sudo systemctl reload nginx重载配置,浏览器按Ctrl+F5硬刷新清除本地缓存后验证样式加载情况。
问题3:POST请求返回
CSRF Failed: CSRF token missing错误 加了@csrf_exempt仍报错的核心原因是装饰器顺序错误,以及DRF默认认证类的强制校验逻辑,按以下步骤修复:
- 调整装饰器顺序:Python装饰器执行顺序为从下往上包装,你当前写法中
@csrf_exempt在最外层,会被内层的@api_view装饰器覆盖效果,将@csrf_exempt调整到离视图函数最近的位置:
@api_view(['POST']) @csrf_exempt def student_login(request): if request.method == 'POST': name = request.data['name'] password= request.data['password'] try: user_obj = Admission.objects.get(name = name, password = password) return Response({"Token": user_obj.student_token}, status=status.HTTP_200_OK) except Admission.DoesNotExist: return Response({"Error": "Invalid username or password!"}, status=status.HTTP_400_BAD_REQUEST) return Response({"Error": "Something went wrong!"}, status=status.HTTP_400_BAD_REQUEST)
- 排查DRF默认认证类拦截:如果settings.py的REST_FRAMEWORK配置中把
SessionAuthentication设为默认认证类,DRF会对所有POST请求强制做CSRF校验,若你的接口是前后端分离/客户端调用、不走Cookie会话认证,可以直接给该视图清空认证类、放开权限:
from rest_framework.decorators import authentication_classes, permission_classes from rest_framework.permissions import AllowAny @api_view(['POST']) @csrf_exempt @authentication_classes([]) @permission_classes([AllowAny]) def student_login(request): # 原有业务逻辑保持不变
- 若为前端带Cookie的同域请求场景,不要用
@csrf_exempt绕过校验,在settings.py中配置CSRF_TRUSTED_ORIGINS = ["https://你的业务域名"],前端请求头中携带从Cookie读取到的csrftoken值即可正常通过校验。 - 代码修改完成后记得重启Gunicorn服务再测试接口。
内容的提问来源于stack exchange,提问作者Athif Saheer
相关产品推荐
相关产品推荐

