Skip to content

Commit 218b625

Browse files
author
aiden_lu
committed
Extend model.
1 parent bc1cc8c commit 218b625

File tree

5 files changed

+69
-10
lines changed

5 files changed

+69
-10
lines changed

drf_api_logger/admin.py

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
from datetime import timedelta
22

33
from django.conf import settings
4-
from django.contrib import admin
4+
from django.contrib import admin, messages
55
from django.db.models import Count
66
from django.http import HttpResponse
77

8+
from rest_framework.test import APIClient
9+
810
from drf_api_logger.utils import database_log_enabled
911

12+
1013
if database_log_enabled():
1114
from drf_api_logger.models import APILogsModel
1215
from django.utils.translation import gettext_lazy as _
@@ -77,7 +80,7 @@ def queryset(self, request, queryset):
7780

7881
class APILogsAdmin(admin.ModelAdmin, ExportCsvMixin):
7982

80-
actions = ["export_as_csv"]
83+
actions = ["retry", "export_as_csv"]
8184

8285
def __init__(self, model, admin_site):
8386
super().__init__(model, admin_site)
@@ -96,12 +99,13 @@ def added_on_time(self, obj):
9699
added_on_time.short_description = 'Added on'
97100

98101
list_per_page = 20
99-
list_display = ('id', 'api', 'method', 'status_code', 'execution_time', 'added_on_time',)
100-
list_filter = ('added_on', 'status_code', 'method',)
102+
list_display = ('id', 'api', 'method', 'result_code', 'request_user', 'execution_time', 'added_on_time',)
103+
list_filter = ('added_on', 'result_code', 'method',)
101104
search_fields = ('body', 'response', 'headers', 'api',)
102105
readonly_fields = (
103106
'execution_time', 'client_ip_address', 'api',
104-
'headers', 'body', 'method', 'response', 'status_code', 'added_on_time',
107+
'headers', 'body', 'method', 'response',
108+
'result_code', 'request_user', 'added_on_time',
105109
)
106110
exclude = ('added_on',)
107111

@@ -116,12 +120,12 @@ def changelist_view(self, request, extra_context=None):
116120
except:
117121
return response
118122
analytics_model = filtered_query_set.values('added_on__date').annotate(total=Count('id')).order_by('total')
119-
status_code_count_mode = filtered_query_set.values('id').values('status_code').annotate(
120-
total=Count('id')).order_by('status_code')
123+
status_code_count_mode = filtered_query_set.values('id').values('result_code').annotate(
124+
total=Count('id')).order_by('result_code')
121125
status_code_count_keys = list()
122126
status_code_count_values = list()
123127
for item in status_code_count_mode:
124-
status_code_count_keys.append(item.get('status_code'))
128+
status_code_count_keys.append(item.get('result_code'))
125129
status_code_count_values.append(item.get('total'))
126130
extra_context = dict(
127131
analytics=analytics_model,
@@ -152,5 +156,31 @@ def has_add_permission(self, request, obj=None):
152156
def has_change_permission(self, request, obj=None):
153157
return False
154158

159+
def retry(self, request, queryset):
160+
"""
161+
Perform retry
162+
"""
163+
if hasattr(settings, "DRF_API_LOGGER_RETRY_AUTH_TOKEN"):
164+
self.message_user(
165+
request,
166+
"You must set 'DRF_API_LOGGER_RETRY_AUTH_TOKEN' in django settings before making a retry request.",
167+
level=messages.ERROR
168+
)
169+
return
170+
171+
if len(queryset) > 1:
172+
self.message_user(request, "You cannot retry in batch!", level=messages.ERROR)
173+
return
174+
175+
api_log = queryset[0]
176+
client = APIClient()
177+
client.force_authenticate(token=settings.DRF_API_LOGGER_RETRY_AUTH_TOKEN)
178+
client.request(
179+
api_log.method,
180+
api_log.api,
181+
data=self.body,
182+
format='json',
183+
)
184+
155185

156186
admin.site.register(APILogsModel, APILogsAdmin)

drf_api_logger/middleware/api_logger_middleware.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
import json
22
import time
3-
import bleach
43
from django.conf import settings
54
from django.urls import resolve
65
from django.utils import timezone
76

87
from drf_api_logger import API_LOGGER_SIGNAL
98
from drf_api_logger.start_logger_when_server_starts import LOGGER_THREAD
10-
from drf_api_logger.utils import get_headers, get_client_ip, mask_sensitive_data
9+
from drf_api_logger.utils import get_headers, get_client_ip, mask_sensitive_data, get_result_code
1110

1211
"""
1312
File: api_logger_middleware.py
@@ -51,6 +50,10 @@ def __init__(self, get_response):
5150
settings.DRF_API_LOGGER_METHODS) is list:
5251
self.DRF_API_LOGGER_METHODS = settings.DRF_API_LOGGER_METHODS
5352

53+
self.DRF_API_LOGGER_RESULT_CODE_KEY = 'ret'
54+
if hasattr(settings, 'DRF_API_LOGGER_RESULT_CODE_KEY'):
55+
self.DRF_API_LOGGER_RESULT_CODE_KEY = settings.DRF_API_LOGGER_RESULT_CODE_KEY
56+
5457
def __call__(self, request):
5558

5659
# Run only if logger is enabled.
@@ -117,6 +120,8 @@ def __call__(self, request):
117120
client_ip_address=get_client_ip(request),
118121
response=mask_sensitive_data(response_body),
119122
status_code=response.status_code,
123+
result_code=get_result_code(response_body, self.DRF_API_LOGGER_RESULT_CODE_KEY),
124+
request_user=request.user if not request.user.is_anonymous else None,
120125
execution_time=time.time() - start_time,
121126
added_on=timezone.now()
122127
)

drf_api_logger/models.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
from django.conf import settings
12
from django.db import models
3+
from user_agents import parse
24

35
from drf_api_logger.utils import database_log_enabled
46

@@ -28,12 +30,24 @@ class APILogsModel(BaseModel):
2830
client_ip_address = models.CharField(max_length=50)
2931
response = models.TextField()
3032
status_code = models.PositiveSmallIntegerField(help_text='Response status code', db_index=True)
33+
result_code = models.PositiveSmallIntegerField(help_text='Result code', null=True, db_index=True)
34+
request_user = models.ForeignKey(settings.AUTH_USER, null=True, on_delete=models.CASCADE, help_text="Request User")
35+
retry_times = models.IntegerField(default=0)
3136
execution_time = models.DecimalField(decimal_places=5, max_digits=8,
3237
help_text='Server execution time (Not complete response time.)')
3338

3439
def __str__(self):
3540
return self.api
3641

42+
@property
43+
def browser(self):
44+
ua_string = self.headers.get("USER_AGENT")
45+
if ua_string is None:
46+
return "Unknown"
47+
48+
user_agent = parse(ua_string)
49+
return f"{user_agent.browser.family} {user_agent.browser.version_string}"
50+
3751
class Meta:
3852
db_table = 'drf_api_logs'
3953
verbose_name = 'API Log'

drf_api_logger/utils.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,3 +67,10 @@ def mask_sensitive_data(data):
6767
data[key] = [mask_sensitive_data(item) for item in data[key]]
6868

6969
return data
70+
71+
72+
def get_result_code(request_body, key):
73+
try:
74+
return request_body.get(key)
75+
except AttributeError:
76+
pass

requirements.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,6 @@ twine==3.4.1
3030
urllib3==1.26.4
3131
webencodings==0.5.1
3232
zipp==3.4.1
33+
pyyaml==6.0
34+
ua-parser==0.10.0
35+
user-agents==2.2.0

0 commit comments

Comments
 (0)