From 13cc531c5d1ca09c71fe1170aec7b529ee6180c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniele=20Vigan=C3=B2?= Date: Tue, 19 Apr 2022 14:17:26 +0200 Subject: [PATCH] Add search function and ui refactor --- ram/portal/templates/base.html | 174 +++++++++++++++++ ram/portal/templates/home.html | 181 +----------------- .../templates/{ => includes}/footer.html | 0 .../templates/{ => includes}/login.html | 0 ram/portal/templates/includes/search.html | 5 + ram/portal/templates/page.html | 108 ++--------- ram/portal/templates/search.html | 41 ++++ ram/portal/urls.py | 12 +- ram/portal/views.py | 68 ++++++- ram/ram/settings.py | 2 +- ram/ram/urls.py | 4 +- 11 files changed, 320 insertions(+), 275 deletions(-) create mode 100644 ram/portal/templates/base.html rename ram/portal/templates/{ => includes}/footer.html (100%) rename ram/portal/templates/{ => includes}/login.html (100%) create mode 100644 ram/portal/templates/includes/search.html create mode 100644 ram/portal/templates/search.html diff --git a/ram/portal/templates/base.html b/ram/portal/templates/base.html new file mode 100644 index 0000000..6693210 --- /dev/null +++ b/ram/portal/templates/base.html @@ -0,0 +1,174 @@ +{% load static %} +{% load solo_tags %} +{% load markdown %} +{% get_solo 'portal.SiteConfiguration' as site_conf %} + + + + + + + + + + {{ site_conf.site_name }} + + + + + + + + + + +
+ +
+ +
+
+
+ + +
+
+
+ {% block header %}{% endblock %} +
+
+
+
+
+ +
+ {% block cards %} + {% for r in rolling_stock %} +
+
+ {% for i in r.image.all %} + {% if i.is_thumbnail %}Card image cap{% endif %} + {% endfor %} +
+

{{ r }}

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Data
Type{{ r.rolling_class.type }}
Company{{ r.rolling_class.company }}
Class{{ r.rolling_class.identifier }}
Road number{{ r.road_number }}
Era{{ r.era }}
Manufacturer{% if r.manufacturer.website %}{% endif %}{{ r.manufacturer }}{% if r.manufacturer.website %}{% endif %} +
Scale{{ r.scale }}
SKU{{ r.sku }}
+ {% if r.decoder %} + + + + + + + + + + + + + + + + +
DCC data
Decoder{{ r.decoder }}
Address{{ r.address }}
+ {% endif %} +
+ Show all data + {% if request.user.is_staff %}Edit{% endif %} +
+ {% if r.tags.all %} +

Tags: + {% for t in r.tags.all %} + {{ t.name }}{# new line is required #} + {% endfor %} +

+ {% endif %} +
+ Updated {{ r.updated_time | date:"M d, Y H:m" }} +
+
+
+
+ {% endfor %} + {% endblock %} +
+
+
{% block pagination %}{% endblock %}
+
+ + + {% block extra_content %}{% endblock %} +
+{% include 'includes/footer.html' %} + + + + diff --git a/ram/portal/templates/home.html b/ram/portal/templates/home.html index a6316d0..f249b6d 100644 --- a/ram/portal/templates/home.html +++ b/ram/portal/templates/home.html @@ -1,175 +1,12 @@ -{% load static %} -{% load solo_tags %} +{% extends "base.html" %} {% load markdown %} -{% get_solo 'portal.SiteConfiguration' as site_conf %} - - - - - - - - - {{ site_conf.site_name }} - - - - - - - - - - -
- -
- -
-
-
-
+ {% block header %}

About

{{ site_conf.about | markdown | safe }}

-
-
-
+ {% endblock %} -
-
- -
- {% for r in rolling_stock %} -
-
- {% for i in r.image.all %} - {% if i.is_thumbnail %}Card image cap{% endif %} - {% endfor %} -
-

{{ r }}

- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Data
Type{{ r.rolling_class.type }}
Company{{ r.rolling_class.company }}
Class{{ r.rolling_class.identifier }}
Road number{{ r.road_number }}
Era{{ r.era }}
-
- - - - - - - - - - - - - - - - - - - -
Model data
Manufacturer{% if r.manufacturer.website %}{% endif %}{{ r.manufacturer }}{% if r.manufacturer.website %}{% endif %} -
Scale{{ r.scale }}
SKU{{ r.sku }}
-
- {% if r.decoder %} -
- - - - - - - - - - - - - - - - -
DCC data
Decoder{{ r.decoder }}
Address{{ r.address }}
-
- {% endif %} -
- - {% if r.decoder %} - - {% endif %} - Show all data - {% if request.user.is_staff %}Edit{% endif %} -
- {% if r.tags.all %} -

Tags: - {% for t in r.tags.all %} - {{ t.name }}{# new line is required #} - {% endfor %} -

- {% endif %} -
- Updated {{ r.updated_time | date:"M d, Y H:m" }} -
-
-
-
- {% endfor %} -
-
-
+ {% block pagination %} {% if rolling_stock.has_other_pages %} {% endif %} -
-
- - -
-{% include 'footer.html' %} - - - + {% endblock %} diff --git a/ram/portal/templates/footer.html b/ram/portal/templates/includes/footer.html similarity index 100% rename from ram/portal/templates/footer.html rename to ram/portal/templates/includes/footer.html diff --git a/ram/portal/templates/login.html b/ram/portal/templates/includes/login.html similarity index 100% rename from ram/portal/templates/login.html rename to ram/portal/templates/includes/login.html diff --git a/ram/portal/templates/includes/search.html b/ram/portal/templates/includes/search.html new file mode 100644 index 0000000..37baf01 --- /dev/null +++ b/ram/portal/templates/includes/search.html @@ -0,0 +1,5 @@ +
+ + +
+ diff --git a/ram/portal/templates/page.html b/ram/portal/templates/page.html index 7a501d1..f36c62d 100644 --- a/ram/portal/templates/page.html +++ b/ram/portal/templates/page.html @@ -1,78 +1,26 @@ -{% load static %} -{% load solo_tags %} +{% extends 'base.html' %} {% load markdown %} -{% get_solo 'portal.SiteConfiguration' as site_conf %} - - - - - - - - - {{ site_conf.site_name }} - - - - - - - - - - -
- -
- -
-
-
-
- + {% block header %}

{{ rolling_stock }}

- {% if rolling_stock.tags.all %} -

Tags: - {% for t in rolling_stock.tags.all %} - {{ t.name }}{# new line is required #} + {% if rolling_stock.tags.all %} +

Tags: + {% for t in rolling_stock.tags.all %} + {{ t.name }}{# new line is required #} + {% endfor %} +

+ {% endif %} + {% endblock %} + {% block cards %} + {% for t in rolling_stock.image.all %} +
+ Rolling stock image +
{% endfor %} -

- {% endif %} -
-
-
-
-
+ {% endblock %} + {% block extra_content %} +
+
-
-
- -
- {% for t in rolling_stock.image.all %} -
- Rolling stock image -
- {% endfor %} -
-
-
-
-{% include 'footer.html' %} - - - + {% endblock %} diff --git a/ram/portal/templates/search.html b/ram/portal/templates/search.html new file mode 100644 index 0000000..bda6965 --- /dev/null +++ b/ram/portal/templates/search.html @@ -0,0 +1,41 @@ +{% extends "base.html" %} + + {% block header %} +

Search: {{ search }}

+

Results found: {{ rolling_stock | length }}

+ {% endblock %} + {% block pagination %} + {% if rolling_stock.has_other_pages %} + + {% endif %} + {% endblock %} diff --git a/ram/portal/urls.py b/ram/portal/urls.py index 9991f27..636f70c 100644 --- a/ram/portal/urls.py +++ b/ram/portal/urls.py @@ -1,8 +1,18 @@ from django.urls import path -from portal.views import GetHome, GetRollingStock +from portal.views import GetHome, GetHomeFiltered, GetRollingStock urlpatterns = [ + path("", GetHome.as_view(), name='index'), path("", GetHome.as_view(), name='index_pagination'), + path( + "search", + GetHomeFiltered.as_view(http_method_names=['post']), + name='index_filtered' + ), + path("search/", + GetHomeFiltered.as_view(), name='index_filtered'), + path("search//", + GetHomeFiltered.as_view(), name='index_filtered_pagination'), path("", GetRollingStock.as_view(), name='rolling_stock'), ] diff --git a/ram/portal/views.py b/ram/portal/views.py index 94b34e6..7c8fef1 100644 --- a/ram/portal/views.py +++ b/ram/portal/views.py @@ -1,16 +1,20 @@ +import operator +from functools import reduce + from django.views import View +from django.http import Http404 +from django.db.models import Q from django.shortcuts import render from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger from portal.utils import get_site_conf -from roster.models import RollingStock, RollingStockImage +from roster.models import RollingStock class GetHome(View): def get(self, request, page=1): site_conf = get_site_conf() rolling_stock = RollingStock.objects.all() - thumbnails = RollingStockImage.objects.filter(is_thumbnail=True) paginator = Paginator(rolling_stock, site_conf.items_per_page) try: @@ -20,9 +24,59 @@ class GetHome(View): except EmptyPage: rolling_stock = paginator.page(paginator.num_pages) - return render(request, 'home.html', { - 'rolling_stock': rolling_stock, - 'thumbnails': thumbnails + return render(request, "home.html", { + "rolling_stock": rolling_stock + }) + + +class GetHomeFiltered(View): + def run_search(self, request, search, page=1): + # if not hasattr(RollingStock, _filter): + # raise Http404 + site_conf = get_site_conf() + # query = { + # _filter: _value + # } + query = reduce(operator.or_, (Q( + Q(rolling_class__identifier__icontains=s) | + Q(rolling_class__description__icontains=s) | + Q(rolling_class__type__type__icontains=s) | + Q(road_number__icontains=s) | + Q(rolling_class__company__name__icontains=s) | + Q(rolling_class__company__country__icontains=s) | + Q(manufacturer__name__icontains=s) | + Q(scale__scale__icontains=s) | + Q(tags__name__icontains=s) + ) for s in search.split())) + rolling_stock = RollingStock.objects.filter(query) + paginator = Paginator(rolling_stock, site_conf.items_per_page) + + try: + rolling_stock = paginator.page(page) + except PageNotAnInteger: + rolling_stock = paginator.page(1) + except EmptyPage: + rolling_stock = paginator.page(paginator.num_pages) + + return rolling_stock + + def get(self, request, search, page=1): + rolling_stock = self.run_search(request, search, page) + + return render(request, "search.html", { + "search": search, + "rolling_stock": rolling_stock + }) + + def post(self, request, page=1): + search = request.POST.get("search") + if not search: + raise Http404 + rolling_stock = self.run_search(request, search, page) + + return render(request, "search.html", { + "search": search, + "rolling_stock": rolling_stock }) @@ -30,6 +84,6 @@ class GetRollingStock(View): def get(self, request, uuid): rolling_stock = RollingStock.objects.get(uuid=uuid) - return render(request, 'page.html', { - 'rolling_stock': rolling_stock, + return render(request, "page.html", { + "rolling_stock": rolling_stock, }) diff --git a/ram/ram/settings.py b/ram/ram/settings.py index e2fdf24..308b02b 100644 --- a/ram/ram/settings.py +++ b/ram/ram/settings.py @@ -28,7 +28,7 @@ SECRET_KEY = ( # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True -ALLOWED_HOSTS = [] +ALLOWED_HOSTS = ["*"] # Application definition diff --git a/ram/ram/urls.py b/ram/ram/urls.py index 493a099..3f27eab 100644 --- a/ram/ram/urls.py +++ b/ram/ram/urls.py @@ -14,18 +14,18 @@ Including another URLconf 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) """ from django.conf import settings +from django.shortcuts import redirect from django.conf.urls.static import static from django.contrib import admin from django.urls import include, path from portal.utils import get_site_conf -from portal.views import GetHome site_conf = get_site_conf() admin.site.site_header = site_conf.site_name urlpatterns = [ - path("", GetHome.as_view(), name="index"), + path("", lambda r: redirect("/portal/")), path("portal/", include("portal.urls")), path("ht/", include("health_check.urls")), path("admin/", admin.site.urls),