Логирование запрос к приложению Django
Вот middleware на который приходит HTTP-запросы:
import time
from threading import local
thread_locals = local()
class RequestTimeMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
thread_locals.path = request.path
thread_locals.sql_count = 0
thread_locals.sql_total = 0
timestamp = time.monotonic()
response = self.get_response(request)
print(
f' Продолжительность запроса {request.path} - '
f'{time.monotonic() - timestamp:.3f} сек. '
f'Количество SQL-запросов {thread_locals.sql_count} '
f'Продолжительность SQL-запросов {thread_locals.sql_total:.3f} '
)
thread_locals.sql_count = 0
thread_locals.sql_total = 0
thread_locals.path = ''
return response
Вот DATABSE engine:
import time
from contextlib import contextmanager
from django.utils.encoding import force_str
from django.db.backends.sqlite3.base import DatabaseWrapper as DjangoDatabaseWrapper
from django.db.backends.utils import CursorWrapper as DjangoCursorWrapper
from middleware.mymiddleware import thread_locals
@contextmanager
def calc_sql_time(sql):
timestamp = time.monotonic()
yield
if hasattr(thread_locals, 'sql_count'):
thread_locals.sql_count +=1
thread_locals.sql_total += time.monotonic() - timestamp
class CursorWrapper(DjangoCursorWrapper):
def execute(self, sql, params=None):
print(f'\f{sql}\f')
path = getattr(thread_locals, 'path', '')
if path:
sql = f'/* {path} */\n{force_str(sql)}\n/* {path} */'
with calc_sql_time(sql):
return super().execute(sql, params)
class DatabaseWrapper(DjangoDatabaseWrapper):
def create_cursor(self, name=None):
cursor = super().create_cursor(name)
return CursorWrapper(cursor, self)
Вот мой view.py:
class ExchangeView(View):
async def get(self, request):
for item in await get_short_names_of_coins():
print(f'Item: {item}')
for item in await get_coins_to_give():
print(f'Item: {item.give_id}')
return render(request, 'main/articles.html', context={'coins_to_give': Order.objects.all()})
@sync_to_async
def get_short_names_of_coins():
try:
coins_name_short = []
for coin in ReceiveGiveCurrencies.objects.values('give__currency_name_short','receive__currency_name_short')\
.exclude(give__currency_name_short='RUB',receive__currency_name_short='RUB')\
.distinct():
if (coin['give__currency_name_short'] not in coins_name_short and coin['give__currency_name_short'] != 'RUB'):
coins_name_short.append(coin['give__currency_name_short'])
if (coin['receive__currency_name_short'] not in coins_name_short and coin['receive__currency_name_short'] != 'RUB'):
coins_name_short.append(coin['receive__currency_name_short'])
return coins_name_short
except:
pass
@sync_to_async
def get_coins_to_give():
"""
Получить монеты, которые может отдать клиент
"""
try:
give_coins = Order.objects.all()
return give_coins
except:
pass
Если я пройду по ссылке и попаду в views.Exchange.get(), то:
- Выведет два SQL-запроса, отправленные в БД sqlite3
- Но при этом напишет мне, что в бд был отправлен всего один запрос. И этот запрос был отправлен из метода get_short_names_of_coins().
- Если убрать метод get_short_names_of_coins() и оставить только get_coins_to_give(), то он выведет мне SQL-запрос, отправленный в БД, но при этом сообщит мне, что запросов не было ВООБЩЕ.
Вот логи:
SELECT DISTINCT "main_givecurrency"."currency_name_short", "main_receivecurrency"."currency_name_short"
FROM "main_receivegivecurrencies"
INNER JOIN "main_givecurrency"
ON ("main_receivegivecurrencies"."give_id" = "main_givecurrency"."id")
INNER JOIN "main_receivecurrency"
ON ("main_receivegivecurrencies"."receive_id" = "main_receivecurrency"."id")
WHERE NOT ("main_givecurrency"."currency_name_short" = %s
AND "main_receivecurrency"."currency_name_short" = %s)
SELECT "main_order"."id", "main_order"."number", "main_order"."random_string",
"main_order"."date_time", "main_order"."give_sum", "main_order"."receive_sum",
"main_order"."give_id", "main_order"."receive_id", "main_order"."give_token_standart_id",
"main_order"."receive_token_standart_id", "main_order"."give_name",
"main_order"."give_address", "main_order"."receive_address_id"
FROM "main_order"
Продолжительность запроса / - 0.069 сек. Количество SQL-запросов 1 Продолжительность SQL-запросов 0.001
Источник: Stack Overflow на русском