From 9f4f03e340ae18221994003587b52403d3cbba03 Mon Sep 17 00:00:00 2001 From: Andrey Smakotin Date: Wed, 24 Dec 2025 13:35:23 +0300 Subject: [PATCH] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B4=D0=BE=D1=81=D1=82=D1=83=D0=BF?= =?UTF-8?q?=D0=B0=20=D0=BA=20=D0=BF=D0=BE=D0=BB=D1=8F=D0=BC=20=D0=B4=D0=BE?= =?UTF-8?q?=D1=81=D1=82=D0=B0=D0=B2=D0=BA=D0=B8=20=D0=BF=D0=BE=D1=81=D0=BB?= =?UTF-8?q?=D0=B5=20=D1=80=D0=B5=D1=84=D0=B0=D0=BA=D1=82=D0=BE=D1=80=D0=B8?= =?UTF-8?q?=D0=BD=D0=B3=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Добавлены свойства обратной совместимости в модель Order для доступа к полям доставки через связь delivery - Исправлены фильтры по delivery_date в модели Customer (get_successful_orders_total) - Исправлены фильтры в orders/filters.py для работы с delivery__delivery_date - Добавлен select_related('delivery') в customer_detail view для оптимизации запросов Исправляет ошибку FieldError: Cannot resolve keyword 'delivery_date' into field --- myproject/customers/models.py | 6 +-- myproject/customers/views.py | 2 +- myproject/orders/filters.py | 14 +++---- myproject/orders/models/order.py | 67 ++++++++++++++++++++++++++++++++ 4 files changed, 78 insertions(+), 11 deletions(-) diff --git a/myproject/customers/models.py b/myproject/customers/models.py index 2b565ce..b6ebdf4 100644 --- a/myproject/customers/models.py +++ b/myproject/customers/models.py @@ -270,11 +270,11 @@ class Customer(models.Model): # Базовый queryset: только успешные заказы queryset = self.orders.filter(status__is_positive_end=True) - # Фильтрация по датам (используем delivery_date) + # Фильтрация по датам (используем delivery__delivery_date после рефакторинга) if start_date: - queryset = queryset.filter(delivery_date__gte=start_date) + queryset = queryset.filter(delivery__delivery_date__gte=start_date) if end_date: - queryset = queryset.filter(delivery_date__lte=end_date) + queryset = queryset.filter(delivery__delivery_date__lte=end_date) # Агрегация суммы result = queryset.aggregate( diff --git a/myproject/customers/views.py b/myproject/customers/views.py index fcc7064..c66f252 100644 --- a/myproject/customers/views.py +++ b/myproject/customers/views.py @@ -131,7 +131,7 @@ def customer_detail(request, pk): ).select_related('order', 'created_by').order_by('-created_at')[:20] # История заказов с пагинацией и оптимизацией запросов - orders_list = customer.orders.select_related('status').order_by('-created_at') + orders_list = customer.orders.select_related('status', 'delivery').order_by('-created_at') paginator = Paginator(orders_list, 10) # 10 заказов на страницу page_number = request.GET.get('page') orders_page = paginator.get_page(page_number) diff --git a/myproject/orders/filters.py b/myproject/orders/filters.py index caf0a6d..fead16a 100644 --- a/myproject/orders/filters.py +++ b/myproject/orders/filters.py @@ -6,7 +6,7 @@ import django_filters from django import forms from django.db.models import Q -from .models import Order, OrderStatus +from .models import Order, OrderStatus, Delivery class OrderFilter(django_filters.FilterSet): @@ -31,9 +31,9 @@ class OrderFilter(django_filters.FilterSet): }) ) - # Фильтр по диапазону дат доставки + # Фильтр по диапазону дат доставки (используем delivery__delivery_date после рефакторинга) delivery_date_after = django_filters.DateFilter( - field_name='delivery_date', + field_name='delivery__delivery_date', lookup_expr='gte', label='Дата доставки от', widget=forms.DateInput(attrs={ @@ -43,7 +43,7 @@ class OrderFilter(django_filters.FilterSet): ) delivery_date_before = django_filters.DateFilter( - field_name='delivery_date', + field_name='delivery__delivery_date', lookup_expr='lte', label='Дата доставки до', widget=forms.DateInput(attrs={ @@ -127,10 +127,10 @@ class OrderFilter(django_filters.FilterSet): def filter_delivery_type(self, queryset, name, value): """ - Кастомный фильтр для типа доставки + Кастомный фильтр для типа доставки (используем delivery__delivery_type после рефакторинга) """ if value == 'delivery': - return queryset.filter(is_delivery=True) + return queryset.filter(delivery__delivery_type=Delivery.DELIVERY_TYPE_COURIER) elif value == 'pickup': - return queryset.filter(is_delivery=False) + return queryset.filter(delivery__delivery_type=Delivery.DELIVERY_TYPE_PICKUP) return queryset diff --git a/myproject/orders/models/order.py b/myproject/orders/models/order.py index 8800385..477c90c 100644 --- a/myproject/orders/models/order.py +++ b/myproject/orders/models/order.py @@ -257,3 +257,70 @@ class Order(models.Model): if hasattr(self, 'delivery'): self.delivery.cost = 0 self.delivery.save(update_fields=['cost']) + + # === Свойства обратной совместимости для доступа к полям доставки === + # Эти свойства обеспечивают доступ к полям Delivery через Order для обратной совместимости + # после рефакторинга, когда поля доставки были перенесены в отдельную модель Delivery + + @property + def delivery_date(self): + """Дата доставки (обратная совместимость)""" + if hasattr(self, 'delivery') and self.delivery: + return self.delivery.delivery_date + return None + + @property + def delivery_time_start(self): + """Время начала доставки (обратная совместимость)""" + if hasattr(self, 'delivery') and self.delivery: + return self.delivery.time_from + return None + + @property + def delivery_time_end(self): + """Время окончания доставки (обратная совместимость)""" + if hasattr(self, 'delivery') and self.delivery: + return self.delivery.time_to + return None + + @property + def delivery_time_window(self): + """Форматированное окно времени доставки (обратная совместимость)""" + if hasattr(self, 'delivery') and self.delivery: + if self.delivery.time_from and self.delivery.time_to: + return f"{self.delivery.time_from.strftime('%H:%M')} - {self.delivery.time_to.strftime('%H:%M')}" + return None + + @property + def delivery_time(self): + """Время доставки (обратная совместимость, использует delivery_time_window)""" + return self.delivery_time_window + + @property + def is_delivery(self): + """Является ли заказ доставкой (обратная совместимость)""" + if hasattr(self, 'delivery') and self.delivery: + from .delivery import Delivery + return self.delivery.delivery_type == Delivery.DELIVERY_TYPE_COURIER + return False + + @property + def delivery_address(self): + """Адрес доставки (обратная совместимость)""" + if hasattr(self, 'delivery') and self.delivery: + return self.delivery.address + return None + + @property + def delivery_cost(self): + """Стоимость доставки (обратная совместимость)""" + if hasattr(self, 'delivery') and self.delivery: + return self.delivery.cost + return 0 + + @property + def pickup_warehouse(self): + """Склад самовывоза (обратная совместимость)""" + if hasattr(self, 'delivery') and self.delivery: + return self.delivery.pickup_warehouse + return None