search presets

This commit is contained in:
vabene1111
2021-09-30 13:46:49 +02:00
parent b61512da77
commit 20db5cfd74
3 changed files with 62 additions and 10 deletions

View File

@ -392,6 +392,7 @@ class SearchPreferenceForm(forms.ModelForm):
prefix = 'search' prefix = 'search'
trigram_threshold = forms.DecimalField(min_value=0.01, max_value=1, decimal_places=2, widget=NumberInput(attrs={'class': "form-control-range", 'type': 'range'}), trigram_threshold = forms.DecimalField(min_value=0.01, max_value=1, decimal_places=2, widget=NumberInput(attrs={'class': "form-control-range", 'type': 'range'}),
help_text=_('Determines how fuzzy a search is if it uses trigram similarity matching (e.g. low values mean more typos are ignored).')) help_text=_('Determines how fuzzy a search is if it uses trigram similarity matching (e.g. low values mean more typos are ignored).'))
preset = forms.CharField(widget=forms.HiddenInput(),required=False)
class Meta: class Meta:
model = SearchPreference model = SearchPreference

View File

@ -163,10 +163,35 @@
<div class="tab-pane {% if active_tab == 'search' %} active {% endif %}" id="search" role="tabpanel" <div class="tab-pane {% if active_tab == 'search' %} active {% endif %}" id="search" role="tabpanel"
aria-labelledby="search-tab"> aria-labelledby="search-tab">
<h4>{% trans 'Search Settings' %}</h4> <h4>{% trans 'Search Settings' %}</h4>
<form action="." method="post"> {% trans 'There are many options to configure the search depending on your personal preferences.' %}
{% trans 'Usually you do <b>not need</b> to configure any of them and can just stick with either the default or one of the following presets.' %}
{% trans 'If you do want to configure the search you can read about the different options <a href="/docs/search/">here</a>.' %}
<div class="card-deck mt-4">
<div class="card">
<div class="card-body">
<h5 class="card-title">{% trans 'Fuzzy' %}</h5>
<p class="card-text">{% trans 'Find what you need even if your search or the recipe contains typos. Might return more results than needed to make sure you find what you are looking for.' %}</p>
<p class="card-text"><small class="text-muted">{% trans 'This is the default behavior' %}</small></p>
<button class="btn btn-primary card-link" onclick="applyPreset('fuzzy')">{% trans 'Apply' %}</button>
</div>
</div>
<div class="card">
<div class="card-body">
<h5 class="card-title">{% trans 'Percise' %}</h5>
<p class="card-text">{% trans 'Allows fine control over search results but might not return results if too many spelling mistakes are made.' %}</p>
<p class="card-text"><small class="text-muted">{% trans 'Perfect for large Databases' %}</small></p>
<button class="btn btn-primary card-link" onclick="applyPreset('precise')">{% trans 'Apply' %}</button>
</div>
</div>
</div>
<hr/>
<form action="./#search" method="post" id="id_search_form">
{% csrf_token %} {% csrf_token %}
{{ search_form|crispy }} {{ search_form|crispy }}
<button class="btn btn-success" type="submit" name="search_form"><i <button class="btn btn-success" type="submit" name="search_form" id="search_form_button"><i
class="fas fa-save"></i> {% trans 'Save' %}</button> class="fas fa-save"></i> {% trans 'Save' %}</button>
</form> </form>
</div> </div>
@ -178,6 +203,10 @@
$('#id_search-trigram_threshold').get(0).type = 'range'; $('#id_search-trigram_threshold').get(0).type = 'range';
}) })
function applyPreset (preset){
$('#id_search-preset').val(preset)
$('#search_form_button').click()
}
function copyToken() { function copyToken() {
let token = $('#id_token'); let token = $('#id_token');

View File

@ -29,7 +29,7 @@ from cookbook.forms import (CommentForm, Recipe, User,
from cookbook.helper.permission_helper import group_required, share_link_valid, has_group_permission from cookbook.helper.permission_helper import group_required, share_link_valid, has_group_permission
from cookbook.models import (Comment, CookLog, InviteLink, MealPlan, from cookbook.models import (Comment, CookLog, InviteLink, MealPlan,
ViewLog, ShoppingList, Space, Keyword, RecipeImport, Unit, ViewLog, ShoppingList, Space, Keyword, RecipeImport, Unit,
Food, UserFile, ShareLink) Food, UserFile, ShareLink, SearchPreference, SearchFields)
from cookbook.tables import (CookLogTable, RecipeTable, RecipeTableSmall, from cookbook.tables import (CookLogTable, RecipeTable, RecipeTableSmall,
ViewLogTable, InviteLinkTable) ViewLogTable, InviteLinkTable)
from cookbook.views.data import Object from cookbook.views.data import Object
@ -219,10 +219,12 @@ def books(request):
def meal_plan(request): def meal_plan(request):
return render(request, 'meal_plan.html', {}) return render(request, 'meal_plan.html', {})
@group_required('user') @group_required('user')
def meal_plan_new(request): def meal_plan_new(request):
return render(request, 'meal_plan_new.html', {}) return render(request, 'meal_plan_new.html', {})
@group_required('user') @group_required('user')
def supermarket(request): def supermarket(request):
return render(request, 'supermarket.html', {}) return render(request, 'supermarket.html', {})
@ -344,11 +346,11 @@ def user_settings(request):
if not sp: if not sp:
sp = SearchPreferenceForm(user=request.user) sp = SearchPreferenceForm(user=request.user)
fields_searched = ( fields_searched = (
len(search_form.cleaned_data['icontains']) len(search_form.cleaned_data['icontains'])
+ len(search_form.cleaned_data['istartswith']) + len(search_form.cleaned_data['istartswith'])
+ len(search_form.cleaned_data['trigram']) + len(search_form.cleaned_data['trigram'])
+ len(search_form.cleaned_data['fulltext'])) + len(search_form.cleaned_data['fulltext'])
# TODO add 'recommended' option )
if fields_searched == 0: if fields_searched == 0:
search_form.add_error(None, _('You must select at least one field to search!')) search_form.add_error(None, _('You must select at least one field to search!'))
search_error = True search_error = True
@ -368,6 +370,26 @@ def user_settings(request):
sp.fulltext.set(search_form.cleaned_data['fulltext']) sp.fulltext.set(search_form.cleaned_data['fulltext'])
sp.trigram_threshold = search_form.cleaned_data['trigram_threshold'] sp.trigram_threshold = search_form.cleaned_data['trigram_threshold']
if search_form.cleaned_data['preset'] == 'fuzzy':
sp.search = SearchPreference.SIMPLE
sp.lookup = True
sp.unaccent.set([SearchFields.objects.get(name='Name')])
sp.icontains.set([SearchFields.objects.get(name='Name')])
sp.istartswith.clear()
sp.trigram.set([SearchFields.objects.get(name='Name')])
sp.fulltext.clear()
sp.trigram_threshold = 0.1
if search_form.cleaned_data['preset'] == 'precise':
sp.search = SearchPreference.WEB
sp.lookup = True
sp.unaccent.set(SearchFields.objects.all())
sp.icontains.clear()
sp.istartswith.set([SearchFields.objects.get(name='Name')])
sp.trigram.clear()
sp.fulltext.set(SearchFields.objects.all())
sp.trigram_threshold = 0.1
sp.save() sp.save()
if up: if up:
preference_form = UserPreferenceForm(instance=up) preference_form = UserPreferenceForm(instance=up)
@ -417,8 +439,8 @@ def history(request):
@group_required('admin') @group_required('admin')
def system(request): def system(request):
postgres = False if ( postgres = False if (
settings.DATABASES['default']['ENGINE'] == 'django.db.backends.postgresql_psycopg2' # noqa: E501 settings.DATABASES['default']['ENGINE'] == 'django.db.backends.postgresql_psycopg2' # noqa: E501
or settings.DATABASES['default']['ENGINE'] == 'django.db.backends.postgresql' # noqa: E501 or settings.DATABASES['default']['ENGINE'] == 'django.db.backends.postgresql' # noqa: E501
) else True ) else True
secret_key = False if os.getenv('SECRET_KEY') else True secret_key = False if os.getenv('SECRET_KEY') else True