mirror of
https://github.com/daniviga/django-ram.git
synced 2025-08-04 21:27:49 +02:00
Add more filters and search refactoring
This commit is contained in:
@@ -114,7 +114,7 @@ class Tag(models.Model):
|
|||||||
|
|
||||||
|
|
||||||
@receiver(models.signals.pre_save, sender=Tag)
|
@receiver(models.signals.pre_save, sender=Tag)
|
||||||
def tag_pre_save(sender, instance, **kwargs):
|
def slug_pre_save(sender, instance, **kwargs):
|
||||||
instance.slug = slugify(instance.name)
|
instance.slug = slugify(instance.name)
|
||||||
|
|
||||||
|
|
||||||
|
@@ -81,8 +81,9 @@
|
|||||||
Roster
|
Roster
|
||||||
</a>
|
</a>
|
||||||
<ul class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
|
<ul class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
|
||||||
<li><a class="dropdown-item" href="{% url 'roster' %}">All roster</a></li>
|
<li><a class="dropdown-item" href="{% url 'roster' %}">Rolling stock</a></li>
|
||||||
<li><a class="dropdown-item" href="{% url 'companies' %}">Companies</a></li>
|
<li><a class="dropdown-item" href="{% url 'companies' %}">Companies</a></li>
|
||||||
|
<li><a class="dropdown-item" href="{% url 'types' %}">Types</a></li>
|
||||||
<li><a class="dropdown-item" href="{% url 'scales' %}">Scales</a></li>
|
<li><a class="dropdown-item" href="{% url 'scales' %}">Scales</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
@@ -38,7 +38,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<th scope="row">Company</th>
|
<th scope="row">Company</th>
|
||||||
<td>
|
<td>
|
||||||
<a href="{% url 'filtered' _filter="company" search=d.rolling_class.company.safe_name %}"><abbr title="{{ d.rolling_class.company.extended_name }}">{{ d.rolling_class.company }}</abbr></a>
|
<a href="{% url 'filtered' _filter="company" search=d.rolling_class.company.pk %}"><abbr title="{{ d.rolling_class.company.extended_name }}">{{ d.rolling_class.company }}</abbr></a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -56,12 +56,12 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<th width="35%" scope="row">Manufacturer</th>
|
<th width="35%" scope="row">Manufacturer</th>
|
||||||
<td>{%if d.manufacturer %}
|
<td>{%if d.manufacturer %}
|
||||||
<a href="{% url 'filtered' _filter="manufacturer" search=d.manufacturer.safe_name %}">{{ d.manufacturer }}{% if d.manufacturer.website %}</a> <a href="{{ d.manufacturer.website }}" target="_blank"><i class="bi bi-box-arrow-up-right"></i></a>{% endif %}
|
<a href="{% url 'filtered' _filter="manufacturer" search=d.manufacturer.pk %}">{{ d.manufacturer }}{% if d.manufacturer.website %}</a> <a href="{{ d.manufacturer.website }}" target="_blank"><i class="bi bi-box-arrow-up-right"></i></a>{% endif %}
|
||||||
{% endif %}</td>
|
{% endif %}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row">Scale</th>
|
<th scope="row">Scale</th>
|
||||||
<td><a href="{% url 'filtered' _filter="scale" search=d.scale %}"><abbr title="{{ d.scale.ratio }} - {{ d.scale.tracks }}">{{ d.scale }}</abbr></a></td>
|
<td><a href="{% url 'filtered' _filter="scale" search=d.scale.pk %}"><abbr title="{{ d.scale.ratio }} - {{ d.scale.tracks }}">{{ d.scale }}</abbr></a></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row">SKU</th>
|
<th scope="row">SKU</th>
|
||||||
|
@@ -42,7 +42,7 @@
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<div class="d-grid gap-2 mb-1 d-md-block">
|
<div class="d-grid gap-2 mb-1 d-md-block">
|
||||||
<a class="btn btn-sm btn-outline-primary" href="{% url 'filtered' _filter="company" search=d %}">Show all rolling stock</a>
|
<a class="btn btn-sm btn-outline-primary" href="{% url 'filtered' _filter="company" search=d.pk %}">Show all rolling stock</a>
|
||||||
{% if request.user.is_staff %}<a class="btn btn-sm btn-outline-danger" href="{% url 'admin:metadata_company_change' d.pk %}">Edit</a>{% endif %}
|
{% if request.user.is_staff %}<a class="btn btn-sm btn-outline-danger" href="{% url 'admin:metadata_company_change' d.pk %}">Edit</a>{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
41
ram/portal/templates/filter.html
Normal file
41
ram/portal/templates/filter.html
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
{% extends "cards.html" %}
|
||||||
|
|
||||||
|
{% block pagination %}
|
||||||
|
{% if data.has_other_pages %}
|
||||||
|
<nav aria-label="Page navigation example">
|
||||||
|
<ul class="pagination justify-content-center mt-4 mb-0">
|
||||||
|
{% if data.has_previous %}
|
||||||
|
<li class="page-item">
|
||||||
|
<a class="page-link" href="{% url 'filtered_pagination' _filter=filter search=search page=data.previous_page_number %}#rolling-stock" tabindex="-1">Previous</a>
|
||||||
|
</li>
|
||||||
|
{% else %}
|
||||||
|
<li class="page-item disabled">
|
||||||
|
<span class="page-link">Previous</span>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
{% for i in page_range %}
|
||||||
|
{% if data.number == i %}
|
||||||
|
<li class="page-item active">
|
||||||
|
<span class="page-link">{{ i }}</span></span>
|
||||||
|
</li>
|
||||||
|
{% else %}
|
||||||
|
{% if i == data.paginator.ELLIPSIS %}
|
||||||
|
<li class="page-item"><span class="page-link">{{ i }}</span></li>
|
||||||
|
{% else %}
|
||||||
|
<li class="page-item"><a class="page-link" href="{% url 'filtered_pagination' _filter=filter search=search page=i %}#rolling-stock">{{ i }}</a></li>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% if data.has_next %}
|
||||||
|
<li class="page-item">
|
||||||
|
<a class="page-link" href="{% url 'filtered_pagination' _filter=filter search=search page=data.next_page_number %}#rolling-stock" tabindex="-1">Next</a>
|
||||||
|
</li>
|
||||||
|
{% else %}
|
||||||
|
<li class="page-item disabled">
|
||||||
|
<span class="page-link">Next</span>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
{% endif %}
|
||||||
|
{% endblock %}
|
@@ -1,6 +1,12 @@
|
|||||||
<form class="d-flex needs-validation" action="{% url 'search' %}" method="post" novalidate>
|
<form class="d-flex needs-validation" action="{% url 'search' %}" method="post" novalidate>
|
||||||
<div class="input-group has-validation">
|
<div class="input-group has-validation">
|
||||||
<input class="form-control me-2" type="search" placeholder="Search" aria-label="Search" name="search" id="searchValidation" required>
|
<input class="form-control me-2" type="search" list="datalistOptions" placeholder="Search" aria-label="Search" name="search" id="searchValidation" required>
|
||||||
|
<datalist id="datalistOptions">
|
||||||
|
<option value="company: ">
|
||||||
|
<option value="manufacturer: ">
|
||||||
|
<option value="scale: ">
|
||||||
|
<option value="type: ">
|
||||||
|
</datalist>
|
||||||
<button class="btn btn-outline-primary" type="submit">Search</button>
|
<button class="btn btn-outline-primary" type="submit">Search</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
@@ -34,7 +34,7 @@
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<div class="d-grid gap-2 mb-1 d-md-block">
|
<div class="d-grid gap-2 mb-1 d-md-block">
|
||||||
<a class="btn btn-sm btn-outline-primary" href="{% url 'filtered' _filter="manufacturer" search=d.safe_name %}">Show all rolling stock</a>
|
<a class="btn btn-sm btn-outline-primary" href="{% url 'filtered' _filter="manufacturer" search=d.pk %}">Show all rolling stock</a>
|
||||||
{% if request.user.is_staff %}<a class="btn btn-sm btn-outline-danger" href="{% url 'admin:metadata_manufacturer_change' d.pk %}">Edit</a>{% endif %}
|
{% if request.user.is_staff %}<a class="btn btn-sm btn-outline-danger" href="{% url 'admin:metadata_manufacturer_change' d.pk %}">Edit</a>{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -32,7 +32,7 @@
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<div class="d-grid gap-2 mb-1 d-md-block">
|
<div class="d-grid gap-2 mb-1 d-md-block">
|
||||||
<a class="btn btn-sm btn-outline-primary" href="{% url 'filtered' _filter="scale" search=d %}">Show all rolling stock</a>
|
<a class="btn btn-sm btn-outline-primary" href="{% url 'filtered' _filter="scale" search=d.pk %}">Show all rolling stock</a>
|
||||||
{% if request.user.is_staff %}<a class="btn btn-sm btn-outline-danger" href="{% url 'admin:metadata_scale_change' d.pk %}">Edit</a>{% endif %}
|
{% if request.user.is_staff %}<a class="btn btn-sm btn-outline-danger" href="{% url 'admin:metadata_scale_change' d.pk %}">Edit</a>{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -1,15 +1,12 @@
|
|||||||
{% extends "cards.html" %}
|
{% extends "cards.html" %}
|
||||||
|
|
||||||
{% block header %}
|
|
||||||
<p class="lead text-muted">Results found: {{ matches }}</p>
|
|
||||||
{% endblock %}
|
|
||||||
{% block pagination %}
|
{% block pagination %}
|
||||||
{% if data.has_other_pages %}
|
{% if data.has_other_pages %}
|
||||||
<nav aria-label="Page navigation example">
|
<nav aria-label="Page navigation example">
|
||||||
<ul class="pagination justify-content-center mt-4 mb-0">
|
<ul class="pagination justify-content-center mt-4 mb-0">
|
||||||
{% if data.has_previous %}
|
{% if data.has_previous %}
|
||||||
<li class="page-item">
|
<li class="page-item">
|
||||||
<a class="page-link" href="{% url 'filtered_pagination' _filter=filter search=search page=data.previous_page_number %}#rolling-stock" tabindex="-1">Previous</a>
|
<a class="page-link" href="{% url 'search_pagination' search=encoded_search page=data.previous_page_number %}#rolling-stock" tabindex="-1">Previous</a>
|
||||||
</li>
|
</li>
|
||||||
{% else %}
|
{% else %}
|
||||||
<li class="page-item disabled">
|
<li class="page-item disabled">
|
||||||
@@ -25,13 +22,13 @@
|
|||||||
{% if i == data.paginator.ELLIPSIS %}
|
{% if i == data.paginator.ELLIPSIS %}
|
||||||
<li class="page-item"><span class="page-link">{{ i }}</span></li>
|
<li class="page-item"><span class="page-link">{{ i }}</span></li>
|
||||||
{% else %}
|
{% else %}
|
||||||
<li class="page-item"><a class="page-link" href="{% url 'filtered_pagination' _filter=filter search=search page=i %}#rolling-stock">{{ i }}</a></li>
|
<li class="page-item"><a class="page-link" href="{% url 'search_pagination' search=encoded_search page=i %}#rolling-stock">{{ i }}</a></li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% if data.has_next %}
|
{% if data.has_next %}
|
||||||
<li class="page-item">
|
<li class="page-item">
|
||||||
<a class="page-link" href="{% url 'filtered_pagination' _filter=filter search=search page=data.next_page_number %}#rolling-stock" tabindex="-1">Next</a>
|
<a class="page-link" href="{% url 'search_pagination' search=encoded_search page=data.next_page_number %}#rolling-stock" tabindex="-1">Next</a>
|
||||||
</li>
|
</li>
|
||||||
{% else %}
|
{% else %}
|
||||||
<li class="page-item disabled">
|
<li class="page-item disabled">
|
||||||
|
73
ram/portal/templates/types.html
Normal file
73
ram/portal/templates/types.html
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
{% extends "cards.html" %}
|
||||||
|
|
||||||
|
{% block cards %}
|
||||||
|
{% for d in data %}
|
||||||
|
<div class="col">
|
||||||
|
<div class="card shadow-sm">
|
||||||
|
<div class="card-body">
|
||||||
|
<p class="card-text"><strong>{{ d }}</strong></p>
|
||||||
|
<table class="table table-striped">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th colspan="2" scope="row">Type</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<th width="35%" scope="row">Type</th>
|
||||||
|
<td>{{ d.type }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th width="35%" scope="row">Category</th>
|
||||||
|
<td>{{ d.category | title}}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<div class="d-grid gap-2 mb-1 d-md-block">
|
||||||
|
<a class="btn btn-sm btn-outline-primary" href="{% url 'filtered' _filter="type" search=d.pk %}">Show all rolling stock</a>
|
||||||
|
{% if request.user.is_staff %}<a class="btn btn-sm btn-outline-danger" href="{% url 'admin:metadata_scale_change' d.pk %}">Edit</a>{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
{% endblock %}
|
||||||
|
{% block pagination %}
|
||||||
|
{% if data.has_other_pages %}
|
||||||
|
<nav aria-label="Page navigation example">
|
||||||
|
<ul class="pagination justify-content-center mt-4 mb-0">
|
||||||
|
{% if data.has_previous %}
|
||||||
|
<li class="page-item">
|
||||||
|
<a class="page-link" href="{% url 'scales_pagination' page=data.previous_page_number %}#rolling-stock" tabindex="-1">Previous</a>
|
||||||
|
</li>
|
||||||
|
{% else %}
|
||||||
|
<li class="page-item disabled">
|
||||||
|
<span class="page-link">Previous</span>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
{% for i in page_range %}
|
||||||
|
{% if data.number == i %}
|
||||||
|
<li class="page-item active">
|
||||||
|
<span class="page-link">{{ i }}</span></span>
|
||||||
|
</li>
|
||||||
|
{% else %}
|
||||||
|
{% if i == data.paginator.ELLIPSIS %}
|
||||||
|
<li class="page-item"><span class="page-link">{{ i }}</span></li>
|
||||||
|
{% else %}
|
||||||
|
<li class="page-item"><a class="page-link" href="{% url 'scales_pagination' page=i %}#rolling-stock">{{ i }}</a></li>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% if data.has_next %}
|
||||||
|
<li class="page-item">
|
||||||
|
<a class="page-link" href="{% url 'scales_pagination' page=data.next_page_number %}#rolling-stock" tabindex="-1">Next</a>
|
||||||
|
</li>
|
||||||
|
{% else %}
|
||||||
|
<li class="page-item disabled">
|
||||||
|
<span class="page-link">Next</span>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
{% endif %}
|
||||||
|
{% endblock %}
|
@@ -11,6 +11,8 @@ from portal.views import (
|
|||||||
Companies,
|
Companies,
|
||||||
Manufacturers,
|
Manufacturers,
|
||||||
Scales,
|
Scales,
|
||||||
|
Types,
|
||||||
|
SearchRoster,
|
||||||
)
|
)
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
@@ -22,11 +24,6 @@ urlpatterns = [
|
|||||||
GetFlatpage.as_view(),
|
GetFlatpage.as_view(),
|
||||||
name="flatpage",
|
name="flatpage",
|
||||||
),
|
),
|
||||||
path(
|
|
||||||
"search",
|
|
||||||
GetRosterFiltered.as_view(http_method_names=["post"]),
|
|
||||||
name="search",
|
|
||||||
),
|
|
||||||
path("consists", Consists.as_view(), name="consists"),
|
path("consists", Consists.as_view(), name="consists"),
|
||||||
path(
|
path(
|
||||||
"consists/<int:page>", Consists.as_view(), name="consists_pagination"
|
"consists/<int:page>", Consists.as_view(), name="consists_pagination"
|
||||||
@@ -54,7 +51,19 @@ urlpatterns = [
|
|||||||
name="manufacturers_pagination",
|
name="manufacturers_pagination",
|
||||||
),
|
),
|
||||||
path("scales", Scales.as_view(), name="scales"),
|
path("scales", Scales.as_view(), name="scales"),
|
||||||
path("scales/<int:page>", Scales.as_view(), name="scales_pagination"),
|
path("scales/<int:page>", Types.as_view(), name="scales_pagination"),
|
||||||
|
path("types", Types.as_view(), name="types"),
|
||||||
|
path("types/<int:page>", Types.as_view(), name="types_pagination"),
|
||||||
|
path(
|
||||||
|
"search",
|
||||||
|
SearchRoster.as_view(http_method_names=["post"]),
|
||||||
|
name="search",
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
"search/<str:search>/<int:page>",
|
||||||
|
SearchRoster.as_view(),
|
||||||
|
name="search_pagination",
|
||||||
|
),
|
||||||
path(
|
path(
|
||||||
"<str:_filter>/<str:search>",
|
"<str:_filter>/<str:search>",
|
||||||
GetRosterFiltered.as_view(),
|
GetRosterFiltered.as_view(),
|
||||||
|
@@ -1,19 +1,20 @@
|
|||||||
|
import base64
|
||||||
import operator
|
import operator
|
||||||
from functools import reduce
|
from functools import reduce
|
||||||
from urllib.parse import quote_plus, unquote_plus
|
from urllib.parse import unquote_plus
|
||||||
|
|
||||||
from django.views import View
|
from django.views import View
|
||||||
from django.http import Http404
|
from django.http import Http404, HttpResponseBadRequest
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render, get_object_or_404
|
||||||
from django.core.exceptions import ObjectDoesNotExist
|
from django.core.exceptions import ObjectDoesNotExist
|
||||||
from django.core.paginator import Paginator, PageNotAnInteger
|
from django.core.paginator import Paginator
|
||||||
|
|
||||||
from portal.utils import get_site_conf
|
from portal.utils import get_site_conf
|
||||||
from portal.models import Flatpage
|
from portal.models import Flatpage
|
||||||
from roster.models import RollingStock
|
from roster.models import RollingStock
|
||||||
from consist.models import Consist
|
from consist.models import Consist
|
||||||
from metadata.models import Company, Manufacturer, Scale
|
from metadata.models import Company, Manufacturer, Scale, RollingStockType, Tag
|
||||||
|
|
||||||
|
|
||||||
def order_by_fields():
|
def order_by_fields():
|
||||||
@@ -62,15 +63,15 @@ class GetData(View):
|
|||||||
|
|
||||||
class GetRoster(GetData):
|
class GetRoster(GetData):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.title = "Roster"
|
self.title = "Rolling stock"
|
||||||
self.template = "roster.html"
|
self.template = "roster.html"
|
||||||
self.data = RollingStock.objects.order_by(*order_by_fields())
|
self.data = RollingStock.objects.order_by(*order_by_fields())
|
||||||
|
|
||||||
|
|
||||||
class GetRosterFiltered(View):
|
class SearchRoster(View):
|
||||||
def run_search(self, request, search, _filter, page=1):
|
def run_search(self, request, search, _filter, page=1):
|
||||||
site_conf = get_site_conf()
|
site_conf = get_site_conf()
|
||||||
if _filter == "search":
|
if _filter is None:
|
||||||
query = reduce(
|
query = reduce(
|
||||||
operator.or_,
|
operator.or_,
|
||||||
(
|
(
|
||||||
@@ -89,6 +90,11 @@ class GetRosterFiltered(View):
|
|||||||
for s in search.split()
|
for s in search.split()
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
elif _filter == "type":
|
||||||
|
query = Q(
|
||||||
|
Q(rolling_class__type__type__icontains=search)
|
||||||
|
| Q(rolling_class__type__category__icontains=search)
|
||||||
|
)
|
||||||
elif _filter == "company":
|
elif _filter == "company":
|
||||||
query = Q(
|
query = Q(
|
||||||
Q(rolling_class__company__name__icontains=search)
|
Q(rolling_class__company__name__icontains=search)
|
||||||
@@ -96,13 +102,11 @@ class GetRosterFiltered(View):
|
|||||||
)
|
)
|
||||||
elif _filter == "manufacturer":
|
elif _filter == "manufacturer":
|
||||||
query = Q(
|
query = Q(
|
||||||
Q(manufacturer__name__iexact=search)
|
Q(manufacturer__name__icontains=search)
|
||||||
| Q(rolling_class__manufacturer__name__icontains=search)
|
| Q(rolling_class__manufacturer__name__icontains=search)
|
||||||
)
|
)
|
||||||
elif _filter == "scale":
|
elif _filter == "scale":
|
||||||
query = Q(scale__scale__iexact=search)
|
query = Q(scale__scale__icontains=search)
|
||||||
elif _filter == "tag":
|
|
||||||
query = Q(tags__slug__iexact=search)
|
|
||||||
else:
|
else:
|
||||||
raise Http404
|
raise Http404
|
||||||
|
|
||||||
@@ -121,47 +125,105 @@ class GetRosterFiltered(View):
|
|||||||
|
|
||||||
return rolling_stock, matches, page_range
|
return rolling_stock, matches, page_range
|
||||||
|
|
||||||
def get(self, request, search, _filter="search", page=1):
|
def split_search(self, search):
|
||||||
search_unsafe = unquote_plus(search) # expected to be encoded
|
search = search.strip().split(":")
|
||||||
|
if not search:
|
||||||
|
raise Http404
|
||||||
|
elif len(search) == 1: # no filter
|
||||||
|
_filter = None
|
||||||
|
search = search[0].strip()
|
||||||
|
elif len(search) == 2: # filter: search
|
||||||
|
_filter = search[0].strip().lower()
|
||||||
|
search = search[1].strip()
|
||||||
|
else:
|
||||||
|
return HttpResponseBadRequest
|
||||||
|
|
||||||
|
return _filter, search
|
||||||
|
|
||||||
|
def get(self, request, search, page=1):
|
||||||
|
try:
|
||||||
|
encoded_search = search
|
||||||
|
search = base64.b64decode(search.encode()).decode()
|
||||||
|
except Exception:
|
||||||
|
encoded_search = base64.b64encode(
|
||||||
|
search.encode()).decode()
|
||||||
|
_filter, keyword = self.split_search(search)
|
||||||
rolling_stock, matches, page_range = self.run_search(
|
rolling_stock, matches, page_range = self.run_search(
|
||||||
request, search_unsafe, _filter, page
|
request, keyword, _filter, page
|
||||||
)
|
)
|
||||||
|
|
||||||
return render(
|
return render(
|
||||||
request,
|
request,
|
||||||
"search.html",
|
"search.html",
|
||||||
{
|
{
|
||||||
"title": "{0}: {1}".format(
|
"title": "Search: \"{}\"".format(search),
|
||||||
_filter.capitalize(), search_unsafe),
|
|
||||||
"search": search,
|
"search": search,
|
||||||
"search_unsafe": search_unsafe,
|
"encoded_search": encoded_search,
|
||||||
"filter": _filter,
|
|
||||||
"matches": matches,
|
"matches": matches,
|
||||||
"data": rolling_stock,
|
"data": rolling_stock,
|
||||||
"page_range": page_range,
|
"page_range": page_range,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
def post(self, request, _filter="search", page=1):
|
def post(self, request, page=1):
|
||||||
search = request.POST.get("search")
|
search = request.POST.get("search")
|
||||||
# search = quote_plus(request.POST.get("search"), safe="&")
|
return self.get(request, search, page)
|
||||||
# search_unsafe = unquote_plus(search)
|
|
||||||
if not search:
|
|
||||||
|
class GetRosterFiltered(View):
|
||||||
|
def run_filter(self, request, search, _filter, page=1):
|
||||||
|
site_conf = get_site_conf()
|
||||||
|
if _filter == "type":
|
||||||
|
title = get_object_or_404(RollingStockType, pk=search)
|
||||||
|
query = Q(rolling_class__type__pk=search)
|
||||||
|
elif _filter == "company":
|
||||||
|
title = get_object_or_404(Company, pk=search)
|
||||||
|
query = Q(rolling_class__company__pk=search)
|
||||||
|
elif _filter == "manufacturer":
|
||||||
|
title = Manufacturer.objects.get(pk=search)
|
||||||
|
query = Q(
|
||||||
|
Q(rolling_class__manufacturer__pk=search)
|
||||||
|
| Q(manufacturer__pk=search)
|
||||||
|
)
|
||||||
|
elif _filter == "scale":
|
||||||
|
title = get_object_or_404(Scale, pk=search)
|
||||||
|
query = Q(scale__pk=search)
|
||||||
|
elif _filter == "tag":
|
||||||
|
title = get_object_or_404(Tag, slug=search)
|
||||||
|
query = Q(tags__slug__iexact=search)
|
||||||
|
else:
|
||||||
raise Http404
|
raise Http404
|
||||||
rolling_stock, matches, page_range = self.run_search(
|
|
||||||
|
rolling_stock = (
|
||||||
|
RollingStock.objects.filter(query)
|
||||||
|
.distinct()
|
||||||
|
.order_by(*order_by_fields())
|
||||||
|
)
|
||||||
|
matches = rolling_stock.count()
|
||||||
|
|
||||||
|
paginator = Paginator(rolling_stock, site_conf.items_per_page)
|
||||||
|
rolling_stock = paginator.get_page(page)
|
||||||
|
page_range = paginator.get_elided_page_range(
|
||||||
|
rolling_stock.number, on_each_side=2, on_ends=1
|
||||||
|
)
|
||||||
|
|
||||||
|
return rolling_stock, title, matches, page_range
|
||||||
|
|
||||||
|
def get(self, request, search, _filter, page=1):
|
||||||
|
data, title, matches, page_range = self.run_filter(
|
||||||
request, search, _filter, page
|
request, search, _filter, page
|
||||||
)
|
)
|
||||||
|
|
||||||
return render(
|
return render(
|
||||||
request,
|
request,
|
||||||
"search.html",
|
"filter.html",
|
||||||
{
|
{
|
||||||
"title": "{0}: {1}".format(_filter.capitalize(), search),
|
"title": "{0}: {1}".format(
|
||||||
|
_filter.capitalize(), title),
|
||||||
"search": search,
|
"search": search,
|
||||||
# "search_unsafe": search_unsafe,
|
|
||||||
"filter": _filter,
|
"filter": _filter,
|
||||||
"matches": matches,
|
"matches": matches,
|
||||||
"data": rolling_stock,
|
"data": data,
|
||||||
"page_range": page_range,
|
"page_range": page_range,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@@ -271,6 +333,13 @@ class Scales(GetData):
|
|||||||
self.data = Scale.objects.all()
|
self.data = Scale.objects.all()
|
||||||
|
|
||||||
|
|
||||||
|
class Types(GetData):
|
||||||
|
def __init__(self):
|
||||||
|
self.title = "Types"
|
||||||
|
self.template = "types.html"
|
||||||
|
self.data = RollingStockType.objects.all()
|
||||||
|
|
||||||
|
|
||||||
class GetFlatpage(View):
|
class GetFlatpage(View):
|
||||||
def get(self, request, flatpage):
|
def get(self, request, flatpage):
|
||||||
try:
|
try:
|
||||||
|
Reference in New Issue
Block a user