diff --git a/myproject/customers/views.py b/myproject/customers/views.py index 3fc5f11..26c15e6 100644 --- a/myproject/customers/views.py +++ b/myproject/customers/views.py @@ -29,13 +29,23 @@ def customer_list(request): customers = Customer.objects.all() if query: - # Try to normalize the phone number for searching + # Используем ту же логику поиска, что и в AJAX API (api_search_customers) + # Это обеспечивает согласованность между веб-интерфейсом и API + + # Нормализуем номер телефона phone_normalized = normalize_query_phone(query) - customers = customers.filter( - Q(name__icontains=query) | - Q(email__icontains=query) | - Q(phone__icontains=phone_normalized) - ) + + # Определяем стратегию поиска + strategy, search_value = determine_search_strategy(query) + + # Строим Q-объект для поиска (единая функция) + q_objects = build_customer_search_query(query, strategy, search_value) + + # Добавляем поиск по телефону + if phone_normalized: + q_objects |= Q(phone__icontains=phone_normalized) + + customers = customers.filter(q_objects) customers = customers.order_by('-created_at') @@ -157,6 +167,44 @@ def determine_search_strategy(query): return ('name_only', query) +def build_customer_search_query(query, strategy, search_value): + """ + Строит Q-объект для поиска клиентов на основе стратегии. + + Используется в customer_list() и api_search_customers() для единообразия. + + Args: + query: Исходный поисковый запрос (для fallback) + strategy: Стратегия поиска (из determine_search_strategy) + search_value: Значение для поиска (из determine_search_strategy) + + Returns: + Q-объект для фильтрации Customer.objects + """ + if strategy == 'name_only': + return Q(name__icontains=search_value) + + elif strategy == 'email_prefix': + # Query вида "team_x3m@" — ищем email, начинающиеся с "team_x3m" + return Q(email__istartswith=search_value) + + elif strategy == 'email_domain': + # Query вида "@bk" — ищем все email с доменом "@bk.*" + return Q(email__icontains=f'@{search_value}') + + elif strategy == 'email_full': + # Query вида "test@bk.ru" — полный поиск по email + return Q(email__icontains=search_value) + + elif strategy == 'universal': + # Query вида "natul" (3+ символов) — ищем везде + return Q(name__icontains=search_value) | Q(email__icontains=search_value) + + else: + # На случай неизвестной стратегии (не должно быть) + return Q(name__icontains=query) + + @require_http_methods(["GET"]) def api_search_customers(request): """ @@ -203,31 +251,8 @@ def api_search_customers(request): # Определяем стратегию поиска на основе содержимого query strategy, search_value = determine_search_strategy(query) - # Строим Q-объект в зависимости от стратегии - if strategy == 'name_only': - # Поиск только по имени (для коротких запросов) - q_objects = Q(name__icontains=search_value) - - elif strategy == 'email_prefix': - # Query вида "team_x3m@" — ищем email, начинающиеся с "team_x3m" - # Это решает проблему: не найдёт "natulj@bk.ru" - q_objects = Q(email__istartswith=search_value) - - elif strategy == 'email_domain': - # Query вида "@bk" — ищем все email с доменом "@bk.*" - q_objects = Q(email__icontains=f'@{search_value}') - - elif strategy == 'email_full': - # Query вида "test@bk.ru" — полный поиск по email - q_objects = Q(email__icontains=search_value) - - elif strategy == 'universal': - # Query вида "natul" (3+ символов) — ищем везде - q_objects = Q(name__icontains=search_value) | Q(email__icontains=search_value) - - else: - # На случай неизвестной стратегии (не должно быть) - q_objects = Q(name__icontains=query) + # Строим Q-объект для поиска (единая функция, используется везде) + q_objects = build_customer_search_query(query, strategy, search_value) # Для телефона ищем по нормализованному номеру и по цифрам if phone_normalized: