From 3de58740c6aeddf3ee7a8e0a2eb65fb12f09411e Mon Sep 17 00:00:00 2001 From: Matthew Smith Date: Wed, 16 Oct 2019 18:23:08 +0100 Subject: [PATCH] Added multi-option search along. Added auto hiding of categories in search unless selected. Added field allowing to choose whether category auto-hidden Fixes #353 --- .gitignore | 1 + assets/forms.py | 5 +++ assets/migrations/0013_auto_20191016_1446.py | 22 ++++++++++ assets/models.py | 1 + assets/templates/asset_list.html | 43 +++++++------------ assets/views.py | 44 +++++++++++++------- 6 files changed, 72 insertions(+), 44 deletions(-) create mode 100644 assets/migrations/0013_auto_20191016_1446.py diff --git a/.gitignore b/.gitignore index a0bddbd2..2a3fd944 100644 --- a/.gitignore +++ b/.gitignore @@ -108,3 +108,4 @@ atlassian-ide-plugin.xml com_crashlytics_export_strings.xml crashlytics.properties crashlytics-build.properties +.vscode/launch.json diff --git a/assets/forms.py b/assets/forms.py index 19e00b11..24fbbd3a 100644 --- a/assets/forms.py +++ b/assets/forms.py @@ -10,6 +10,11 @@ class AssetForm(forms.ModelForm): fields = '__all__' +class AssetSearchForm(forms.Form): + query = forms.CharField(required=False) + category = forms.ModelMultipleChoiceField(models.AssetCategory.objects.all(), required=False) + status = forms.ModelMultipleChoiceField(models.AssetStatus.objects.all(), required=False) + class SupplierForm(forms.Form): class Meta: model = models.Supplier diff --git a/assets/migrations/0013_auto_20191016_1446.py b/assets/migrations/0013_auto_20191016_1446.py new file mode 100644 index 00000000..b17b7423 --- /dev/null +++ b/assets/migrations/0013_auto_20191016_1446.py @@ -0,0 +1,22 @@ +# Generated by Django 2.0.13 on 2019-10-16 13:46 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('assets', '0012_auto_20191014_0012'), + ] + + operations = [ + migrations.AlterModelOptions( + name='asset', + options={'ordering': ['asset_id'], 'permissions': (('asset_finance', 'Can see financial data for assets'),)}, + ), + migrations.AddField( + model_name='assetstatus', + name='should_show', + field=models.BooleanField(default=True, help_text='Should this be shown by default in the asset list.'), + ), + ] diff --git a/assets/models.py b/assets/models.py index 603363d3..a25b579f 100644 --- a/assets/models.py +++ b/assets/models.py @@ -24,6 +24,7 @@ class AssetStatus(models.Model): verbose_name_plural = 'Asset Statuses' name = models.CharField(max_length=80) + should_show = models.BooleanField(default=True, help_text="Should this be shown by default in the asset list.") def __str__(self): return self.name diff --git a/assets/templates/asset_list.html b/assets/templates/asset_list.html index c6aa1281..7b8aa640 100644 --- a/assets/templates/asset_list.html +++ b/assets/templates/asset_list.html @@ -1,6 +1,7 @@ {% extends 'base_assets.html' %} {% block title %}List{% endblock %} {% load paginator from filters %} +{% load widget_tweaks %} {% block content %} @@ -11,41 +12,19 @@
{% csrf_token %}
- - + {% render_field form.query|add_class:'form-control' placeholder='Search by Asset ID/Description' style="width: 250px"%} +

- - + + {% render_field form.category|attr:'multiple'|add_class:'form-control selectpicker' data-none-selected-text="Categories" data-header="Categories"%}
- + {% render_field form.status|attr:'multiple'|add_class:'form-control selectpicker' data-none-selected-text="Statuses" data-header="Statuses"%}
@@ -75,5 +54,13 @@ {% endblock %} -{% block js %} +{% load static %} +{% block css %} + + +{% endblock %} + +{% block preload_js %} + + {% endblock %} diff --git a/assets/views.py b/assets/views.py index 43352b79..9d8493bb 100644 --- a/assets/views.py +++ b/assets/views.py @@ -19,39 +19,51 @@ class AssetList(LoginRequiredMixin, generic.ListView): template_name = 'asset_list.html' paginate_by = 40 ordering = ['-pk'] + hide_hidden_status = True def get_queryset(self): - # TODO Feedback to user when search fails - query = self.request.GET.get('query', "") - if len(query) == 0: - queryset = self.model.objects.all() - elif len(query) >= 3: - queryset = self.model.objects.filter(Q(asset_id__exact=query) | Q(description__icontains=query)) + if self.request.method == 'POST': + self.form = forms.AssetSearchForm(data=self.request.POST) + elif self.request.method == 'GET': + self.form = forms.AssetSearchForm(data=self.request.GET) else: - queryset = self.model.objects.filter(Q(asset_id__exact=query)) + self.form = forms.AssetSearchForm(data={}) + form = self.form + if not form.is_valid(): + return self.model.objects.none() - cat = self.request.GET.get('cat', "") - status = self.request.GET.get('status', "") - if cat != "": - queryset = queryset.filter(category__name__exact=cat) - if status != "": - queryset = queryset.filter(status__name__exact=status) + # TODO Feedback to user when search fails + query_string = form.cleaned_data['query'] or "" + if len(query_string) == 0: + queryset = self.model.objects.all() + elif len(query_string) >= 3: + queryset = self.model.objects.filter(Q(asset_id__exact=query_string) | Q(description__icontains=query_string)) + else: + queryset = self.model.objects.filter(Q(asset_id__exact=query_string)) + + if form.cleaned_data['category']: + queryset = queryset.filter(category__in=form.cleaned_data['category']) + + if len(form.cleaned_data['status']) > 0: + queryset = queryset.filter(status__in=form.cleaned_data['status']) + elif self.hide_hidden_status: + queryset = queryset.filter(status__in=models.AssetStatus.objects.filter(should_show=True)) return queryset def get_context_data(self, **kwargs): context = super(AssetList, self).get_context_data(**kwargs) - context["search_name"] = self.request.GET.get('query', "") + context["form"] = self.form context["categories"] = models.AssetCategory.objects.all() - context["category_select"] = self.request.GET.get('cat', "") context["statuses"] = models.AssetStatus.objects.all() - context["status_select"] = self.request.GET.get('status', "") return context class AssetSearch(AssetList): + hide_hidden_status = False + def render_to_response(self, context, **response_kwargs): result = []