mod: улучшена производительность +регистронезависимость
This commit is contained in:
@@ -1,44 +1,57 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
__author__ = 'Sergei Erjemin'
|
__author__ = 'Sergei Erjemin'
|
||||||
|
|
||||||
from django.http import HttpResponse
|
from django.http import HttpResponse, HttpResponseRedirect
|
||||||
from django.shortcuts import HttpResponseRedirect
|
from django.http import HttpRequest
|
||||||
from django.http import HttpRequest, HttpResponse
|
|
||||||
from oknardia.models import Building_Info
|
from oknardia.models import Building_Info
|
||||||
# from time import clock
|
import json
|
||||||
import re
|
import re
|
||||||
import urllib
|
|
||||||
|
|
||||||
|
|
||||||
def autocomplete_addr(request: HttpRequest) -> HttpResponse:
|
def autocomplete_addr(request: HttpRequest) -> HttpResponse:
|
||||||
""" Функция для автозаполнения формы выбора адреса. Получает методом GET переменную "term" и по ее образцу
|
"""Функция для автозаполнения формы выбора адреса.
|
||||||
ищет доступные адреса в базе адреса из таблицы Building_Info
|
|
||||||
|
Получает методом GET переменную "term" и по её образцу ищет доступные адреса
|
||||||
|
в таблице Building_Info. Результаты возвращаются в JSON формате для jQuery UI.
|
||||||
|
|
||||||
:param request: входящий http-запрос
|
:param request: входящий http-запрос
|
||||||
:return response: исходящий http-ответ
|
:return: JSON ответ с массивом адресов или редирект на главную
|
||||||
"""
|
"""
|
||||||
# Для автозаполнения используется JQuery_UI: http://jqueryui.com/
|
if request.method != 'GET' or 'term' not in request.GET:
|
||||||
# Пример и инструкции по использованию: 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:
|
|
||||||
return HttpResponseRedirect("/")
|
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')
|
||||||
|
|||||||
Reference in New Issue
Block a user