Parcourir la source

Add filterable lists

Colin Powell il y a 3 ans
Parent
commit
c0693d88a2

+ 20 - 1
games/urls.py

@@ -18,6 +18,21 @@ urlpatterns = [
         views.LibraryGameList.as_view(),
         name="game_library_list",
     ),
+    path(
+        "publisher/",
+        views.PublisherList.as_view(),
+        name="publisher_list",
+    ),
+    path(
+        "genre/",
+        views.GenreList.as_view(),
+        name="genre_list",
+    ),
+    path(
+        "developer/",
+        views.DeveloperList.as_view(),
+        name="developer_list",
+    ),
     path(
         "<str:slug>/",
         views.GameDetail.as_view(),
@@ -33,7 +48,11 @@ urlpatterns = [
         views.GameSystemDetail.as_view(),
         name="game_system_detail",
     ),
-    path("genre/<str:slug>/", views.GenreDetail.as_view(), name="genre_detail"),
+    path(
+        "genre/<str:slug>/",
+        views.GenreDetail.as_view(),
+        name="genre_detail",
+    ),
     path(
         "publisher/<str:slug>/",
         views.PublisherDetail.as_view(),

+ 46 - 4
games/views.py

@@ -1,24 +1,33 @@
-from django.db.models import F
+from django.db.models import Avg, Count, F
 from django.views.generic import DetailView, ListView
 from django.views.generic.list import MultipleObjectMixin
 
 from .models import Developer, Game, GameSystem, Genre, Publisher
 
+import logging
+
+logger = logging.Logger(__name__)
+
 
 class RecentGameList(ListView):
     model = Game
     paginate_by = 20
-    queryset = Game.objects.order_by("-created")[:20]
+    queryset = Game.objects.order_by("-created")[:200]
 
 
 class LibraryGameList(ListView):
     template_name = "games/game_library_list.html"
     model = Game
-    paginate_by = 200
+    paginate_by = 100
 
     def get_context_data(self, **kwargs):
         game_system_slug = self.request.GET.get("game_system")
-        object_list = Game.objects.order_by(F("rating").desc(nulls_last=True))
+        order_by = self.request.GET.get("order_by", "name")
+        if order_by[0] == "-":
+            order_by = order_by[1:]
+            object_list = Game.objects.order_by(F(order_by).desc(nulls_last=True))
+        else:
+            object_list = Game.objects.order_by(F(order_by).asc(nulls_last=True))
         if game_system_slug:
             object_list = object_list.filter(
                 game_system__retropie_slug=game_system_slug
@@ -29,6 +38,39 @@ class LibraryGameList(ListView):
         return context
 
 
+class FilterableBaseListView(ListView):
+    VALID_ORDERING = ["name", "num_games", "rating"]
+
+    def get_queryset(self, **kwargs):
+        order_by = self.request.GET.get("order_by", "name")
+        queryset = super().get_queryset(**kwargs)
+        queryset = queryset.annotate(num_games=Count("game")).annotate(
+            rating=Avg("game__rating")
+        )
+        if order_by.replace("-", "") not in self.VALID_ORDERING:
+            logger.warning(f"Received invalid filter {order_by}")
+            return queryset
+
+        if order_by[0] == "-":
+            order_by = order_by[1:]
+            queryset = queryset.order_by(F(order_by).desc(nulls_last=True))
+        else:
+            queryset = queryset.order_by(F(order_by).asc(nulls_last=True))
+        return queryset
+
+
+class PublisherList(FilterableBaseListView):
+    model = Publisher
+
+
+class DeveloperList(FilterableBaseListView):
+    model = Developer
+
+
+class GenreList(FilterableBaseListView):
+    model = Genre
+
+
 class GameDetail(DetailView):
     model = Game
 

+ 27 - 0
templates/games/developer_list.html

@@ -0,0 +1,27 @@
+{% extends "base.html" %}
+{% block page_title %}Developers{% endblock %}
+
+{% block title %}All developers{% endblock %}
+
+{% block content %}
+    <table class="table table-bordered table">
+    <thead>
+        <tr>
+        <th scope="col">#</th>
+        <th scope="col">Name</th>
+        <th scope="col">Games</th>
+        <th scope="col">Rating</th>
+        </tr>
+    </thead>
+    <tbody>
+        {% for  developer in object_list %}
+        <tr>
+        <th scope="row"><a href="{{developer.get_absolute_url}}">{{developer.id}}</a></th>
+        <td>{{developer.name}}</td>
+        <td>{{developer.game_set.count}}</td>
+        <td>{{developer.rating_avg}}/100</td>
+        </tr>
+        {% endfor %}
+    </tbody>
+    </table>
+{% endblock %}

+ 5 - 5
templates/games/game_library_list.html

@@ -8,12 +8,12 @@
     <thead>
         <tr>
         <th scope="col">#</th>
-        <th scope="col">Name</th>
+        <th scope="col"><a href="?order_by=name">Name</a></th>
         <th scope="col">System</th>
-        <th scope="col">Rating</th>
-        <th scope="col">Developer</th>
-        <th scope="col">Publisher</th>
-        <th scope="col">Genre</th>
+        <th scope="col"><a href="?order_by={% if not '-rating' in request.get_full_path %}-{% endif %}rating">Rating</a></th>
+        <th scope="col"><a href="?order_by={% if not '-developer' in request.get_full_path %}-{% endif %}developer">Developer</a></th>
+        <th scope="col"><a href="?order_by={% if not '-publisher' in request.get_full_path %}-{% endif %}publisher">Publisher</a></th>
+        <th scope="col"><a href="?order_by={% if not '-genre' in request.get_full_path %}-{% endif %}genre">Genre</a></th>
         </tr>
     </thead>
     <tbody>

+ 27 - 0
templates/games/genre_list.html

@@ -0,0 +1,27 @@
+{% extends "base.html" %}
+{% block page_title %}Genres{% endblock %}
+
+{% block title %}All genres{% endblock %}
+
+{% block content %}
+    <table class="table table-bordered table">
+    <thead>
+        <tr>
+        <th scope="col">#</th>
+        <th scope="col">Name</th>
+        <th scope="col">Games</th>
+        <th scope="col">Rating</th>
+        </tr>
+    </thead>
+    <tbody>
+        {% for  genre in object_list %}
+        <tr>
+        <th scope="row"><a href="{{genre.get_absolute_url}}">{{genre.id}}</a></th>
+        <td>{{genre.name}}</td>
+        <td>{{genre.game_set.count}}</td>
+        <td>{{genre.rating_avg}}/100</td>
+        </tr>
+        {% endfor %}
+    </tbody>
+    </table>
+{% endblock %}

+ 27 - 0
templates/games/publisher_list.html

@@ -0,0 +1,27 @@
+{% extends "base.html" %}
+{% block page_title %}Publishers{% endblock %}
+
+{% block title %}All publishers{% endblock %}
+
+{% block content %}
+    <table class="table table-bordered table">
+    <thead>
+        <tr>
+        <th scope="col">#</th>
+        <th scope="col">Name</th>
+        <th scope="col">Games</th>
+        <th scope="col">Rating</th>
+        </tr>
+    </thead>
+    <tbody>
+        {% for  publisher in object_list %}
+        <tr>
+        <th scope="row"><a href="{{publisher.get_absolute_url}}">{{publisher.id}}</a></th>
+        <td>{{publisher.name}}</td>
+        <td>{{publisher.game_set.count}}</td>
+        <td>{{publisher.rating_avg}}/100</td>
+        </tr>
+        {% endfor %}
+    </tbody>
+    </table>
+{% endblock %}