Логирование запрос к приложению Django

Рейтинг: 0Ответов: 0Опубликовано: 06.03.2023

Вот 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(), то:

  1. Выведет два SQL-запроса, отправленные в БД sqlite3
  2. Но при этом напишет мне, что в бд был отправлен всего один запрос. И этот запрос был отправлен из метода get_short_names_of_coins().
  3. Если убрать метод 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 

Ответы

Ответов пока нет.