From 792627d89d7c3d26bf26321c8181a5214d170316 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=92=D1=8F=D1=87=D0=B5=D1=81=D0=BB=D0=B0=D0=B2=20=D0=9C?= =?UTF-8?q?=D0=B5=D0=BD=D1=8E=D1=85=D0=BE=D0=B2?= Date: Sat, 6 Apr 2024 09:30:49 +0300 Subject: [PATCH] Refactor the code. --- src/companies/api/viewsets/point.py | 7 ++-- src/companies/models/material.py | 7 ++-- .../services/materials_statistic/validator.py | 12 +++---- .../test_materials_statistic_validator.py | 32 +++++++++++-------- tests/fixtures/apps/app/__init__.py | 3 +- tests/fixtures/apps/app/api.py | 8 ----- 6 files changed, 32 insertions(+), 37 deletions(-) diff --git a/src/companies/api/viewsets/point.py b/src/companies/api/viewsets/point.py index 23bc164..4431ae2 100644 --- a/src/companies/api/viewsets/point.py +++ b/src/companies/api/viewsets/point.py @@ -4,7 +4,7 @@ from rest_framework.decorators import action from rest_framework.permissions import IsAuthenticatedOrReadOnly from rest_framework.response import Response -from rest_framework.viewsets import ModelViewSet +from rest_framework.viewsets import ModelViewSet, ReadOnlyModelViewSet from django.db.models import QuerySet @@ -42,13 +42,12 @@ def add_employees(self, *args: Any, **kwargs: Any) -> Response: return Response(EmployeeSerializer(employee).data) -class MaterialsStatisticViewSet(ModelViewSet): - http_method_names = ["get"] +class MaterialsStatisticViewSet(ReadOnlyModelViewSet): serializer_class = MaterialsStatisticSerializer permission_classes = [IsCompanyOwner] def get_queryset(self) -> QuerySet[Material]: - DateValidatorService(self.request)() + DateValidatorService(self.request.query_params)() return Material.objects.statistic( self.kwargs["point_pk"], self.request.query_params.get("date_from"), diff --git a/src/companies/models/material.py b/src/companies/models/material.py index cf23b3f..6c40ab4 100644 --- a/src/companies/models/material.py +++ b/src/companies/models/material.py @@ -28,13 +28,12 @@ class Meta: class MaterialQuerySet(QuerySet): def statistic(self, point_id: int, date_from: str | None = None, date_to: str | None = None) -> Self: now = timezone.now().date() - q_date_from = Q(date__gte=date_from) if date_from else Q(date__gte=(now - timedelta(days=30))) - q_date_to = Q(date__lte=date_to) if date_to else Q(date__lte=now) + date_filter = Q(date__gte=date_from or (now - timedelta(days=30))) & Q(date__lte=date_to or now) stock_queryset = ( StockMaterial.objects.select_related("stock__date") .filter(stock__point__id=point_id) .annotate(date=F("stock__date")) - .filter(q_date_from & q_date_to) + .filter(date_filter) ) stocks = ( stock_queryset.filter(material_id=OuterRef("id")) @@ -54,7 +53,7 @@ def statistic(self, point_id: int, date_from: str | None = None, date_to: str | .filter(material__stock__point_id=point_id) .select_related("material__material_id") .annotate(date=TruncDate("modified")) - .filter(q_date_from & q_date_to) + .filter(date_filter) ) usage = ( usage_queryset.filter(material__material_id=OuterRef("id")) diff --git a/src/companies/services/materials_statistic/validator.py b/src/companies/services/materials_statistic/validator.py index 9d1f60e..976e19b 100644 --- a/src/companies/services/materials_statistic/validator.py +++ b/src/companies/services/materials_statistic/validator.py @@ -3,23 +3,23 @@ from typing import Callable from rest_framework.exceptions import ValidationError -from rest_framework.request import Request + +from django.http.request import QueryDict from app.services import BaseService @dataclass class DateValidatorService(BaseService): - request: Request + query_params: QueryDict | None def valide_date_query_params(self) -> None: - query_params = self.request.query_params - if not query_params: + if not self.query_params: return try: date_format = "%Y-%m-%d" - date_from_str = query_params.get("date_from") - date_to_str = query_params.get("date_to") + date_from_str = self.query_params.get("date_from") + date_to_str = self.query_params.get("date_to") if date_from_str: date_from = datetime.strptime(date_from_str, date_format).date() if date_to_str: diff --git a/tests/apps/companies/services/test_materials_statistic_validator.py b/tests/apps/companies/services/test_materials_statistic_validator.py index 8935744..b4596a3 100644 --- a/tests/apps/companies/services/test_materials_statistic_validator.py +++ b/tests/apps/companies/services/test_materials_statistic_validator.py @@ -1,32 +1,38 @@ import pytest from rest_framework.exceptions import ValidationError -from rest_framework.request import Request + +from django.http.request import QueryDict from companies.services import DateValidatorService -def test_valid_date_params(mock_request: Request, material_date_query_params: dict[str, str]): - mock_request.query_params = material_date_query_params # type: ignore +def test_valid_date_params(material_date_query_params: dict[str, str]): + query_params = QueryDict(mutable=True) + query_params.update(**material_date_query_params) - assert DateValidatorService(mock_request)() is True + assert DateValidatorService(query_params)() is True -def test_only_date_from_param(mock_request: Request, material_date_query_params: dict[str, str]): +def test_only_date_from_param(material_date_query_params: dict[str, str]): del material_date_query_params["date_to"] - mock_request.query_params = material_date_query_params # type: ignore + query_params = QueryDict(mutable=True) + query_params.update(**material_date_query_params) - assert DateValidatorService(mock_request)() is True + assert DateValidatorService(query_params)() is True -def test_only_date_to_param(mock_request: Request, material_date_query_params: dict[str, str]): +def test_only_date_to_param(material_date_query_params: dict[str, str]): del material_date_query_params["date_from"] - mock_request.query_params = material_date_query_params # type: ignore + query_params = QueryDict(mutable=True) + query_params.update(**material_date_query_params) + + assert DateValidatorService(query_params)() is True - assert DateValidatorService(mock_request)() is True +def test_invalid_date_params(invalide_material_date_query_params: dict[str, str]): + query_params = QueryDict(mutable=True) + query_params.update(**invalide_material_date_query_params) -def test_invalid_date_params(mock_request: Request, invalide_material_date_query_params: dict[str, str]): - mock_request.query_params = invalide_material_date_query_params # type: ignore with pytest.raises(ValidationError): - DateValidatorService(mock_request)() + DateValidatorService(query_params)() diff --git a/tests/fixtures/apps/app/__init__.py b/tests/fixtures/apps/app/__init__.py index c2e8e1f..d01aae4 100644 --- a/tests/fixtures/apps/app/__init__.py +++ b/tests/fixtures/apps/app/__init__.py @@ -1,4 +1,4 @@ -from tests.fixtures.apps.app.api import as_anon, as_superuser, as_user, mock_request +from tests.fixtures.apps.app.api import as_anon, as_superuser, as_user from tests.fixtures.apps.app.factory import factory __all__ = [ @@ -6,5 +6,4 @@ "as_superuser", "as_user", "factory", - "mock_request", ] diff --git a/tests/fixtures/apps/app/api.py b/tests/fixtures/apps/app/api.py index 720b6b2..7b9cdc5 100644 --- a/tests/fixtures/apps/app/api.py +++ b/tests/fixtures/apps/app/api.py @@ -1,8 +1,5 @@ import pytest -from pytest_mock import MockerFixture -from rest_framework.request import Request - from app.testing import ApiClient from users.models import User @@ -20,8 +17,3 @@ def as_user(user: User) -> ApiClient: @pytest.fixture def as_superuser(superuser: User) -> ApiClient: return ApiClient(user=superuser) - - -@pytest.fixture -def mock_request(mocker: MockerFixture) -> Request: - return mocker.MagicMock(spec=Request)