如何在Django视图中获取静态文件请求日志及请求IP
解决方案:在Django中记录静态文件请求及IP地址
没问题,我刚好做过类似的需求,给你两个靠谱的方案,都是基于手动托管静态文件来实现日志记录的思路:
方案一:自定义静态文件服务视图(最直接可控)
这个方法就是完全接管静态文件的请求处理,在视图里直接完成日志记录,步骤如下:
配置项目设置
首先确保DEBUG = False(因为DEBUG模式下Django会自动处理静态文件,不会走我们的自定义视图),然后配置静态文件的根目录:# settings.py DEBUG = False STATIC_URL = '/static/' STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles') # 你收集静态文件的目录别忘了先执行
python manage.py collectstatic把所有静态文件收集到STATIC_ROOT里。编写自定义视图
在你的app的views.py里写一个处理静态文件的视图,同时记录请求IP和路径:# views.py import os import logging from django.http import FileResponse, Http404 from django.conf import settings # 配置日志记录器(也可以直接写入数据库,看你需求) logger = logging.getLogger('static_requests') def serve_static(request, path): # 获取请求IP(如果有代理,优先取X-Forwarded-For) client_ip = request.META.get('HTTP_X_FORWARDED_FOR', request.META.get('REMOTE_ADDR')) # 记录日志 logger.info(f"Static file requested: {path} | IP: {client_ip}") # 或者如果要存数据库,这里可以创建日志对象保存 # StaticRequestLog.objects.create(file_path=path, ip_address=client_ip) # 处理文件返回 static_file_path = os.path.join(settings.STATIC_ROOT, path) if not os.path.exists(static_file_path) or not os.path.isfile(static_file_path): raise Http404("Static file not found") return FileResponse(open(static_file_path, 'rb'))配置路由
在项目的urls.py里把静态文件的路由指向这个视图:# urls.py from django.urls import path from . import views urlpatterns = [ # 其他路由... path('static/<path:path>', views.serve_static), ]
方案二:用中间件捕获静态文件请求(无需修改路由逻辑)
如果你不想完全接管静态文件服务,也可以用中间件来拦截所有静态文件的请求并记录日志:
编写中间件
在项目里创建一个middleware.py文件:# middleware.py import logging from django.conf import settings logger = logging.getLogger('static_requests') class StaticRequestLogMiddleware: def __init__(self, get_response): self.get_response = get_response def __call__(self, request): # 判断请求路径是否是静态文件路径 if request.path.startswith(settings.STATIC_URL): client_ip = request.META.get('HTTP_X_FORWARDED_FOR', request.META.get('REMOTE_ADDR')) logger.info(f"Static file requested: {request.path} | IP: {client_ip}") # 同样可以选择写入数据库 response = self.get_response(request) return response注册中间件
在settings.py里把这个中间件添加到MIDDLEWARE列表中(注意顺序,尽量放在靠前的位置,确保能捕获到请求):# settings.py MIDDLEWARE = [ 'yourapp.middleware.StaticRequestLogMiddleware', # 你的中间件路径 # 其他中间件... ]
注意事项
- DEBUG模式的坑:如果是DEBUG=True,Django的
StaticFilesMiddleware会优先处理静态文件请求,导致中间件或者自定义视图捕获不到请求。所以如果要在开发环境测试,需要暂时注释掉django.contrib.staticfiles在INSTALLED_APPS中的配置,或者直接用生产模式测试。 - IP地址准确性:如果你的部署环境有反向代理(比如Nginx),一定要确保代理传递了
X-Forwarded-For头,否则你记录的会是代理服务器的IP而不是用户的真实IP。 - 性能考虑:手动托管静态文件的性能肯定不如Nginx这类专业静态文件服务器,如果是高流量生产环境,建议还是用Nginx托管静态文件,同时在Nginx里配置日志记录,或者通过Nginx把请求转发到Django的日志接口。但如果你的流量不大,上面的方案完全够用。
内容的提问来源于stack exchange,提问作者Tharun Prabakaran
相关产品推荐
相关产品推荐

