diff --git a/config/settings/base.py b/config/settings/base.py index f5648772c..cdf3f264b 100644 --- a/config/settings/base.py +++ b/config/settings/base.py @@ -282,6 +282,7 @@ def FILTERS_VERBOSE_LOOKUPS(): "core.no_cache_middleware.NoCacheMiddleware", "simple_history.middleware.HistoryRequestMiddleware", "axes.middleware.AxesMiddleware", + "core.middleware.DatabaseQueriesMiddleware", ] AUTHENTICATION_BACKENDS = [ diff --git a/core/middleware.py b/core/middleware.py new file mode 100644 index 000000000..f475e394b --- /dev/null +++ b/core/middleware.py @@ -0,0 +1,17 @@ +from django.db import connection + + +class DatabaseQueriesMiddleware: + def __init__(self, get_response): + self.get_response = get_response + + def __call__(self, request): + pre_query_count = len(connection.queries) + + response = self.get_response(request) + + post_query_count = len(connection.queries) + query_count = post_query_count - pre_query_count + print(f"Database queries {query_count}") + + return response diff --git a/docker-compose.yml b/docker-compose.yml index 7d33fcecf..8732b5415 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -18,6 +18,9 @@ services: depends_on: - db - redis + # Required for debuggers to work. + stdin_open: true + tty: true celery: image: fft/web:latest diff --git a/forecast/serialisers.py b/forecast/serialisers.py index 49bf5b29f..ac84879af 100644 --- a/forecast/serialisers.py +++ b/forecast/serialisers.py @@ -25,7 +25,7 @@ def get_month(self, obj): return obj.financial_period.financial_period_code def get_actual(self, obj): - if obj.financial_year_id > get_current_financial_year(): + if obj.financial_year_id > self.context["current_financial_year"]: return False return obj.financial_period.actual_loaded @@ -67,6 +67,7 @@ def get_nac_description(self, obj): return obj.natural_account_code.natural_account_code_description def get_budget(self, obj): + # FIXME: 400+ queries! try this as a prefetch similar to forecast or change to a lookup financial_year = self.context["financial_year"] budget = ( BudgetMonthlyFigure.objects.values( diff --git a/forecast/views/edit_forecast.py b/forecast/views/edit_forecast.py index 4a20de7b4..fd8f092b1 100644 --- a/forecast/views/edit_forecast.py +++ b/forecast/views/edit_forecast.py @@ -83,24 +83,32 @@ def get_financial_codes_for_year(cost_centre_code, financial_year): def get_financial_code_serialiser(cost_centre_code, financial_year): # Only selects the financial codes relevant to the financial year being edited. # Financial codes are used in budgets and forecast/actuals. - forecasts = ForecastMonthlyFigure.objects.filter( + forecasts = ForecastMonthlyFigure.objects.select_related("financial_period").filter( financial_year_id=financial_year, archived_status__isnull=True, ) financial_codes = ( get_financial_codes_for_year(cost_centre_code, financial_year) + .select_related("programme", "natural_account_code") .prefetch_related( Prefetch( "forecast_forecastmonthlyfigures", queryset=forecasts, to_attr="monthly_figure_items", ), - "forecast_forecastmonthlyfigures__financial_period", + # FIXME: check this isn't needed + # "forecast_forecastmonthlyfigures__financial_period", ) .order_by(*edit_forecast_order()) ) + financial_code_serialiser = FinancialCodeSerializer( - financial_codes, many=True, context={"financial_year": financial_year} + financial_codes, + many=True, + context={ + "financial_year": financial_year, + "current_financial_year": get_current_financial_year(), + }, ) return financial_code_serialiser @@ -478,6 +486,7 @@ def get_context_data(self, **kwargs): self.cost_centre_code, self.financial_year, ) + # FIXME: holy moly it's slow! serialiser_data = financial_code_serialiser.data forecast_dump = json.dumps(serialiser_data) if self.financial_year == get_current_financial_year():