Django 记录所有 GET 请求

Django Logging all the GET requests

我正在尝试将出现在控制台中的所有 GET 请求从 django 放入数据库中。例如:

控制台日志:

[23/May/2019 13:58:44] "GET /testapp/ HTTP/1.1" 200 409
[23/May/2019 13:58:45] "GET /testapp/page2/ HTTP/1.1" 200 172

我正在尝试从中获取时间戳、页面 URL 和用户名并将其放入数据库中,因此数据库中的条目看起来像这样:

id  user    pageURL        timeStamp
96  naeem   /testapp/       2019-05-23 09:37:12.640613
97  naeem   /testapp/page2/ 2019-05-23 09:37:13.317271

这是我为中间件编写的代码:

from TestApp.models import ActivityLog


class AccessLogs(object):

    # One-time config
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        response = self.get_response(request)

        # Add the user and page info into DB
        try:
            ActivityLog(user=request.user, pageURL=request.path).save()
        except Exception as e:
            print(e)

        return response

问题是它给了我想要的结果,但是如果我单击可下载的文件或图像,它却得不到结果。就像我在网站上有一张静态图片,点击下载,比如:

<a href="{% static 'TestApp/media/cat.jpg' %}" download>Click here to open image</a>

因此,如果我单击它,它会在控制台中显示图像已下载,但不会将其放入数据库中。有什么办法可以使这项工作?任何帮助将不胜感激!

编辑:settings.py:

import os

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

SECRET_KEY = ''

DEBUG = True

ALLOWED_HOSTS = []

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'TestApp',
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    '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',
    'TestApp.middleware.LoggingMiddleware.AccessLogs',
]

ROOT_URLCONF = 'Test.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.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'Test.wsgi.application'

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}

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',
    },
]

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True

STATIC_URL = '/static/'
MEDIA_URL = '/media/'

STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'media')
]

型号:

from django.db import models

class ActivityLog(models.Model):
    user = models.CharField(max_length=1024)
    pageURL = models.CharField(max_length=1024)
    timeStamp = models.DateTimeField(auto_now_add=True)

    class Meta:
        db_table = "activity_logs"

EDIT2:我试图访问的文件存储在 TestWebsite/TestApp/static/TestApp/media/cat.jpg

TestWebsite/TestApp/url.py:

from django.urls import path

from . import views

urlpatterns = [
    path('', views.homePage, name='homePage'),
    path('page2/', views.homePage2, name='homepage2')
]

TestWebsite/TestWebsite/urls.py

from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
from django.views.static import serve
from django.views.decorators.cache import never_cache

nocache_serve = never_cache(serve)

urlpatterns = [
    path('admin/', admin.site.urls),
    path('testapp/', include('TestApp.url')),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT, view=nocache_serve)

TestWebsite/TestApp/views.py:

from django.shortcuts import render, HttpResponse
import datetime

def homePage(request):
    time = datetime.datetime.now()
    return render(request, "TestApp/homePage.html", {"time": time})

def homePage2(request):
    return render(request, "TestApp/homePage2.html")

一般来说 Django's Middleware 是为了有效的 request/response 管理而创建的。它有自己的阶段(process_request()process_view()process_response())等等。每次请求到达服务器时,都会调用 Middleware (但在提供静态文件时,并不是每次都会发生这种情况)。这是因为缓存行为。 Django 在浏览器缓存中缓存 static/media 文件(使用 Cache-Control header)。当资源被缓存时,下一个请求资源从浏览器缓存中读取并且请求没有到达服务器。 Django 使用 from django.views.static import serve 方法提供 static/media 文件。 (此方法为缓存设置正确的 HTTP headers)。

在您的 urls.py 中添加这些行。这里是最重要的。

from django.conf import settings
from django.conf.urls.static import static
from django.views.static import serve
from django.views.decorators.cache import never_cache

nocache_serve = never_cache(serve) # never_cache is view decorator. we can use here, also. This will set correct HTTP headers to avoid caching behaviour.
urlpatterns = [
    #
    # your path goes here
    #
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT, view=nocache_serve)

settings.py

# I think you already have this configuration in settings.
STATIC_URL = '/static/'
MEDIA_URL = '/media/'
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'media')
]

现在,您可以记录所有传入请求(但不要忘记,避免 static/media 文件的缓存行为是个坏主意)。

添加此代码后不要忘记清除浏览器缓存并重新启动服务器。

希望对您有所帮助。