Merge pull request #85 from revsys/filter-by-category

Filter library results by category
This commit is contained in:
Lacey Williams Henschel
2023-01-09 14:52:25 -08:00
committed by GitHub
6 changed files with 85 additions and 11 deletions

8
libraries/forms.py Normal file
View File

@@ -0,0 +1,8 @@
from django.forms import ModelForm
from .models import Library, Category
class LibraryForm(ModelForm):
class Meta:
model = Library
fields = ["categories"]

View File

@@ -3,6 +3,11 @@ from fastcore.xtras import dict2obj
from model_bakery import baker
@pytest.fixture
def category(db):
return baker.make("libraries.Category", name="Math", slug="math")
@pytest.fixture
def library(db):
return baker.make(

View File

@@ -0,0 +1,6 @@
from ..forms import LibraryForm
def test_library_form_success(tp, library, category):
form = LibraryForm(data={"categories": [category]})
assert form.is_valid() is True

View File

@@ -7,6 +7,25 @@ def test_library_list(library, tp):
tp.response_200(res)
def test_library_list_select_category(library, category, tp):
"""POST /libraries/ to submit a category redirects to the libraries-by-category page"""
res = tp.post("libraries", data={"categories": category.pk})
tp.response_302(res)
def test_libraries_by_category(tp, library, category):
"""GET /libraries-by-category/{slug}/"""
baker.make("libraries.Library", name="Sample")
library.categories.add(category)
res = tp.get("libraries-by-category", category.slug)
tp.response_200(res)
assert "library_list" in res.context
assert len(res.context["library_list"]) == 1
assert library in res.context["library_list"]
assert "category" in res.context
assert res.context["category"] == category
def test_library_detail(library, tp):
"""GET /libraries/{repo}/"""
url = tp.reverse("library-detail", library.slug)

View File

@@ -1,7 +1,14 @@
from django.views.generic import DetailView, ListView
import structlog
from django.shortcuts import redirect
from django.views.generic import DetailView, ListView
from django.views.generic.edit import FormMixin
from .forms import LibraryForm
from .models import Category, Issue, Library, PullRequest
logger = structlog.get_logger()
class CategoryMixin:
def get_context_data(self, **kwargs):
@@ -10,15 +17,26 @@ class CategoryMixin:
return context
class LibraryList(CategoryMixin, ListView):
class LibraryList(CategoryMixin, FormMixin, ListView):
"""List all of our libraries by name"""
form_class = LibraryForm
paginate_by = 25
queryset = (
Library.objects.prefetch_related("authors", "categories").all().order_by("name")
)
template_name = "libraries/list.html"
def post(self, request):
"""User has submitted a form and will be redirected to the right results"""
form = self.get_form()
if form.is_valid():
category = form.cleaned_data["categories"][0]
return redirect("libraries-by-category", category=category.slug)
else:
logger.info("library_list_invalid_category")
return super().get(request)
class LibraryByLetter(CategoryMixin, ListView):
"""List all of our libraries that begin with a certain letter"""
@@ -42,6 +60,17 @@ class LibraryByCategory(CategoryMixin, ListView):
paginate_by = 25
template_name = "libraries/list.html"
def get_context_data(self, **kwargs):
context = super().get_context_data()
category_slug = self.kwargs.get("category")
if category_slug:
try:
category = Category.objects.get(slug=category_slug)
context["category"] = category
except Category.DoesNotExist:
logger.info("libraries_by_category_view_category_not_found")
return context
def get_queryset(self):
category = self.kwargs.get("category")

View File

@@ -5,7 +5,7 @@
{% block content %}
<!-- Breadcrumb used on filtered views -->
<div class="p-3 md:p-0">
<a class="text-orange" href="{% url "libraries" %}">Libraries</a> > Categorized
<a class="text-orange" href="{% url "libraries" %}">Libraries</a> > Categorized{% if category %} > <a class="text-orange" href="{% url "libraries-by-category" category.slug %}">{{ category.name }}</a>{% endif %}
</div>
<!-- end breadcrumb -->
@@ -43,14 +43,21 @@
</span>
<input type="search" name="q" class="w-full md:w-1/3 text-sm text-white bg-charcoal focus:text-charcoal text-orange px-3 py-2 rounded-md" type="text" value="" placeholder="Search Library" />
</div>
<div>
<select class="mb-3 md:mb-0 w-full md:w-auto cursor-pointer block sm:inline-block text-sm uppercase rounded-md bg-black text-orange border border-slate pl-5 pr-11 py-3 mr-3">
<option>Filter by category</option>
{% for c in categories %}
<option value="{{c.name}}">{{ c.name }}</option>
{% endfor %}
</select>
</div>
<!-- Form to select a category -->
<form action="/libraries/" method="post">
{% csrf_token %}
<div>
<label for="id_categories" hidden="true">Categories:</label>
<select name="categories" class="mb-3 md:mb-0 w-full md:w-auto cursor-pointer block sm:inline-block text-sm uppercase rounded-md bg-black text-orange border border-slate pl-5 pr-11 py-3 mr-3" id="id_categories">
<option>Filter by category</option>
{% for c in categories %}
<option value="{{ c.pk }}" {% if category == c %}selected="selected"{% endif %}>{{ c.name }}</option>
{% endfor %}
</select>
</div>
<input type="submit" value="Submit" style="color: red">
</form>
</div>
</div>