Django记录所有GET请求

时间:2019-05-23 10:08:44

标签: django django-middleware django-logging

我正在尝试将控制台中显示的所有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")

1 个答案:

答案 0 :(得分:1)

好的,现在我想向您解释发生了什么。通常,Django's Middleware是为有效的请求/响应管理而创建的。它具有自己的阶段(process_request()process_view()process_response()),依此类推。每次请求到达服务器时,都会调用Middleware(但是在提供静态文件时,并非每次都会发生)。这是由于缓存行为。 Django静态/媒体文件缓存在浏览器缓存中(使用Cache-Control标头)。缓存资源时,在下一个请求上,将从缓存中读取资源,并且请求未到达服务器上。 Django使用from django.views.static import serve方法提供静态/媒体文件。 (此方法设置了正确的HTTP标头进行缓存)。

在您的 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 文件的行为是个坏主意)。

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

希望有帮助。