From d028f853568deaa36025154398220ddc5e74198b Mon Sep 17 00:00:00 2001 From: erjemin Date: Mon, 11 May 2026 20:12:48 +0300 Subject: [PATCH] =?UTF-8?q?mod:=20=D1=83=D0=BB=D1=83=D1=87=D1=88=D0=B5?= =?UTF-8?q?=D0=BD=D0=B0=20=D0=BF=D1=80=D0=BE=D0=B8=D0=B7=D0=B2=D0=BE=D0=B4?= =?UTF-8?q?=D0=B8=D1=82=D0=B5=D0=BB=D1=8C=D0=BD=D0=BE=D1=81=D1=82=D1=8C=20?= =?UTF-8?q?+=D1=80=D0=B5=D0=B3=D0=B8=D1=81=D1=82=D1=80=D0=BE=D0=BD=D0=B5?= =?UTF-8?q?=D0=B7=D0=B0=D0=B2=D0=B8=D1=81=D0=B8=D0=BC=D0=BE=D1=81=D1=82?= =?UTF-8?q?=D1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- oknardia/web/autocomplete_addr.py | 77 ++++++++++++++++++------------- 1 file changed, 45 insertions(+), 32 deletions(-) diff --git a/oknardia/web/autocomplete_addr.py b/oknardia/web/autocomplete_addr.py index d2e32ad..59d7f39 100755 --- a/oknardia/web/autocomplete_addr.py +++ b/oknardia/web/autocomplete_addr.py @@ -1,44 +1,57 @@ # -*- coding: utf-8 -*- __author__ = 'Sergei Erjemin' -from django.http import HttpResponse -from django.shortcuts import HttpResponseRedirect -from django.http import HttpRequest, HttpResponse +from django.http import HttpResponse, HttpResponseRedirect +from django.http import HttpRequest from oknardia.models import Building_Info -# from time import clock +import json import re -import urllib def autocomplete_addr(request: HttpRequest) -> HttpResponse: - """ Функция для автозаполнения формы выбора адреса. Получает методом GET переменную "term" и по ее образцу - ищет доступные адреса в базе адреса из таблицы Building_Info + """Функция для автозаполнения формы выбора адреса. + + Получает методом GET переменную "term" и по её образцу ищет доступные адреса + в таблице Building_Info. Результаты возвращаются в JSON формате для jQuery UI. :param request: входящий http-запрос - :return response: исходящий http-ответ + :return: JSON ответ с массивом адресов или редирект на главную """ - # Для автозаполнения используется JQuery_UI: http://jqueryui.com/ - # Пример и инструкции по использованию: http://professorweb.ru/my/javascript/jquery/level4/4_5.php - # - # ВНИМАНИЕ ТЕХНИЧЕСКИЙ ДОЛГ,: Более навороченный, по описанию лучше подходящий компонент автозаполнения - # https://www.devbridge.com/sourcery/components/jquery-autocomplete/ не заработал. Ну и хрен с ним! - # - # ВНИМАНИЕ ТЕХНИЧЕСКИЙ ДОЛГ: возможен "перегрев" при частом обращении -- [Errno 10053] - # Предположительно из-за отсутсвия csrfmiddlewaretoken-серилизации Django. Проблема пофикусена(?) 2014-11-14 - # tStart = clock() - if request.method == 'GET' and 'term' in request.GET: - part_blocks = re.split(r"[,/;\s.\\:]+", str(request.GET['term'])) - if request.GET['use_filter'] == "only_known": - q_autocomplete = Building_Info.objects.filter(kSeria_Link__kRoot_id__isnull=False) - else: - q_autocomplete = Building_Info.objects - for i in part_blocks: - q_autocomplete = q_autocomplete.filter(sAddress__icontains=i) - q_autocomplete = q_autocomplete.all().order_by('sAddress') - to_response = "" - for i in q_autocomplete[:10]: - to_response += '"' + i.sAddress + u'",' - to_response = '[' + to_response[0:-1] + ']' # Убираем последнюю запятую - return HttpResponse(to_response) - else: + if request.method != 'GET' or 'term' not in request.GET: return HttpResponseRedirect("/") + + # Получаем поисковый термин и очищаем его + search_term = str(request.GET.get('term', '')).strip() + if not search_term: + return HttpResponse('[]', content_type='application/json') + + # Разбиваем на части для поиска по компонентам адреса (город, улица, номер) + part_blocks = re.split(r"[,/;\s.\\:]+", search_term) + part_blocks = [p.strip().lower() for p in part_blocks if p.strip()] # Приводим к нижнему регистру + + # Начинаем с базового набора или фильтруем только по известным сериям + if request.GET.get('use_filter') == "only_known": + q_autocomplete = Building_Info.objects.filter( + kSeria_Link__kRoot_id__isnull=False + ) + else: + q_autocomplete = Building_Info.objects + + # Получаем адреса и фильтруем на уровне Python для гарантированной регистронезависимости + # (особенно важно для русского текста в SQLite и, возможно, других БД) + all_addresses = q_autocomplete.values_list('sAddress', flat=True).distinct() + + filtered_addresses = [] + for address in all_addresses: + address_lower = address.lower() + # Проверяем, содержатся ли все части поиска в адресе (без учета регистра) + if all(part in address_lower for part in part_blocks): + filtered_addresses.append(address) + + # Сортируем и ограничиваем до 10 результатов + addresses = sorted(filtered_addresses)[:10] + + # Конвертируем в JSON (безопаснее, чем ручная конкатенация) + result = json.dumps(list(addresses), ensure_ascii=False) + + return HttpResponse(result, content_type='application/json; charset=utf-8')