У меня есть приложение Django с базой данных Postgres, которое принимает пользовательский ввод, создает регулярное выражение на основе этого ввода и возвращает записи базы данных, которые соответствуют этому регулярному выражению, а также начальной и конечной позициям этого совпадения. Текущая реализация выглядит примерно так:
models.py
:
class SampleInputModel(models.Model):
target_field = models.CharField()
class SampleInputModelForm(ModelForm):
class Meta:
model = SampleInputModel
fields = '__all__'
class RecordObject(models.Model):
record_name = models.TextField()
record_string = models.TextField()
views.py
:
find_regex_match(form_dict, one_record, terminating_word='keyword'):
import re
search_pattern = f'({form_dict['target_field']}).*(terminating_word)'
for match in re.finditer(search_pattern, one_record.record_string):
return '{}\t{}\t{}\t{}\n'.format(
one_record.record_name, match.start(), match.end(),
one_record.record_string[match.start():match.end()]
)
def home(request):
if request.method == 'POST':
form = SampleInputModelForm(request.POST)
if form.is_valid():
form = form.save(commit=False)
form = model_to_dict(form)
results = ''
for one_record in RecordObject.objects.all():
results += find_regex_match(form_dict, one_record)
return render(request, 'results.html', {'results': results})
else:
form = SampleInputModelForm()
return render(request, 'home.html', {'form': form})
Это работает и занимает ~ 1,2 секунды на средний к завершению. Однако я чувствую, что есть лучший способ обработать результаты, чем просто передавать огромную необработанную строку в шаблон для рендеринга. Я хотел переключиться на использование некоторых API Django для фильтрации базы данных, чтобы можно было передавать наборы запросов в шаблоны. Новая версия кода выглядит так:
def home(request):
if request.method == 'POST':
form = SampleInputModelForm(request.POST)
if form.is_valid():
form = form.save(commit=False)
form = model_to_dict(form)
search_pattern = f'({form_dict['target_field']}).*(terminating_word)'
results = RecordObject.objects.filter(record_string__iregex=search_pattern)
return render(request, 'results.html', {'results': results})
...
Этот запрос завершается очень быстро (<0,005 секунды) и кажется более Django -y (и я думаю, что смогу отформатировать вещи намного проще использовать объект QuerySet вместо необработанной строки в результатах. html), но я не знаю, как извлечь нужную мне информацию из результатов. Я попробовал, объединив два подхода: </p>
def home(request):
if request.method == 'POST':
form = SampleInputModelForm(request.POST)
if form.is_valid():
form = form.save(commit=False)
form = model_to_dict(form)
search_pattern = f'({form_dict['target_field']}).*(terminating_word)'
results = ''
for record_match in RecordObject.objects.filter(record_string__iregex=search_pattern):
results += find_regex_match(form_dict, record_match)
return render(request, 'results.html', {'results': results})
...
Но это медленнее, чем два других подхода, в среднем около 3 секунд на выполнение. Это имеет смысл, поскольку я выполняю поиск по регулярному выражению (в основном) дважды. Есть ли лучший способ получить необходимую мне информацию после фильтрации базы данных с помощью регулярного выражения, не жертвуя слишком большой скоростью? Также приветствуются любые общие комментарии к коду. Спасибо!