I'm trying to put all the GET requests that appear in console into the database from django. For example:
console log:
[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
I'm trying to get the timestamp, page URL and user name from it and put in the database, so the entries looks something like this in the database:
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
This is the code I have written for the middleware:
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
The problem is that it gives me the desired result, but it does not get the results if I click on a downloadable file, or an image. Like I have a static image on the website which is downloaded on click, like:
<a href="{% static 'TestApp/media/cat.jpg' %}" download>Click here to open image</a>
So if I click on that, it shows in the console that the image was downloaded, but it doesn't put that in the database. Is there any way to make this work? Any help will be appreciated!
EDIT: 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')
]
Models:
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: The file I'm trying to access is stored in 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")
In general Django's Middleware
are created for effective request/response management. It has own phases (process_request()
, process_view()
, process_response()
) and so on. Every time request reaches on server, Middleware
is called (But This does not happen every time, when serving static files). This is because of caching behaviour. Django
caches static/media files in browser cache (using Cache-Control
header). When resource is cached, on next request resource is read from browser cache and request does not reach on the server. Django
uses from django.views.static import serve
method for serving static/media files. (This method sets correct HTTP
headers for caching).
In your urls.py add these lines. This is the most important here.
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)
# I think you already have this configuration in settings.
STATIC_URL = '/static/'
MEDIA_URL = '/media/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'media')
]
Now, You can log all incoming request (But do not forget, to avoid caching behaviour of static/media files is bad idea).
Hope it helps.