summaryrefslogtreecommitdiffstats
path: root/packages
diff options
context:
space:
mode:
authorJohannes Löthberg <johannes@kyriasis.com>2018-01-02 19:08:10 +0100
committerAngel Velásquez <angvp@archlinux.org>2018-01-02 13:08:10 -0500
commit5538aa8799788e19a1691bd3c2e889bb088e654b (patch)
tree3cc45ae812a8a3d576fe04952a3d0eeba06f8fd7 /packages
parent860a0511a0b465222b45ae3e19b20d07165651fe (diff)
downloadarchweb-5538aa8799788e19a1691bd3c2e889bb088e654b.tar.gz
archweb-5538aa8799788e19a1691bd3c2e889bb088e654b.zip
Add pagination to JSON package search (#73)release_2018-01-02
* Add pagination to JSON search form using Paginator The downside of this is that we can't easily run prefetch_related anymore, but given the limit I don't suspect this to be a problem. Signed-off-by: Johannes Löthberg <johannes@kyriasis.com> * packages/views/search: Add appropriate newlines to search_json Signed-off-by: Johannes Löthberg <johannes@kyriasis.com> * Update package fixture to be the same as devel/fixtures/core.db.tar.gz Signed-off-by: Johannes Löthberg <johannes@kyriasis.com> * packages/tests: Add tests for JSON search pagination Signed-off-by: Johannes Löthberg <johannes@kyriasis.com>
Diffstat (limited to 'packages')
-rw-r--r--packages/tests.py30
-rw-r--r--packages/views/search.py25
2 files changed, 46 insertions, 9 deletions
diff --git a/packages/tests.py b/packages/tests.py
index 69bf2e76..5c70aaf4 100644
--- a/packages/tests.py
+++ b/packages/tests.py
@@ -75,8 +75,9 @@ class PackageSearchJson(TestCase):
response = self.client.get('/packages/search/json/?repository=core')
self.assertEqual(response.status_code, 200)
data = json.loads(response.content)
- self.assertEqual(len(data['results']), 1)
- self.assertEqual(data['results'][0]['pkgname'], 'linux')
+ self.assertEqual(len(data['results']), 5)
+ self.assertEqual(set(map(lambda r: r['pkgname'], data['results'])),
+ {"coreutils", "glibc", "linux", "pacman", "systemd"})
def test_packagename(self):
response = self.client.get('/packages/search/json/?name=linux')
@@ -90,6 +91,23 @@ class PackageSearchJson(TestCase):
data = json.loads(response.content)
self.assertEqual(len(data['results']), 0)
+ def test_limit_four(self):
+ response = self.client.get('/packages/search/json/?limit=4')
+ self.assertEqual(response.status_code, 200)
+ data = json.loads(response.content)
+ self.assertEqual(data['page'], 1)
+ self.assertEqual(data['num_pages'], 2)
+ self.assertEqual(data['limit'], 4)
+ self.assertEqual(len(data['results']), 4)
+
+ def test_second_page(self):
+ response = self.client.get('/packages/search/json/?limit=4&page=2')
+ self.assertEqual(response.status_code, 200)
+ data = json.loads(response.content)
+ self.assertEqual(data['page'], 2)
+ self.assertEqual(data['num_pages'], 2)
+ self.assertEqual(len(data['results']), 1)
+
class PackageSearch(TestCase):
fixtures = ['main/fixtures/arches.json', 'main/fixtures/repos.json',
@@ -113,7 +131,7 @@ class PackageSearch(TestCase):
def test_filter_repo(self):
response = self.client.get('/packages/?repo=Core')
self.assertEqual(response.status_code, 200)
- self.assertIn('1 matching package found', response.content)
+ self.assertIn('5 matching packages found', response.content)
def test_filter_desc(self):
response = self.client.get('/packages/?desc=kernel')
@@ -128,7 +146,7 @@ class PackageSearch(TestCase):
def test_filter_not_flagged(self):
response = self.client.get('/packages/?flagged=Not Flagged')
self.assertEqual(response.status_code, 200)
- self.assertIn('1 matching package found', response.content)
+ self.assertIn('5 matching packages found', response.content)
def test_filter_arch(self):
response = self.client.get('/packages/?arch=any')
@@ -138,11 +156,11 @@ class PackageSearch(TestCase):
def test_filter_maintainer_orphan(self):
response = self.client.get('/packages/?maintainer=orphan')
self.assertEqual(response.status_code, 200)
- self.assertIn('1 matching package found', response.content)
+ self.assertIn('5 matching packages found', response.content)
def test_filter_packager_unknown(self):
response = self.client.get('/packages/?packager=unknown')
self.assertEqual(response.status_code, 200)
- self.assertIn('1 matching package found', response.content)
+ self.assertIn('5 matching packages found', response.content)
# vim: set ts=4 sw=4 et:
diff --git a/packages/views/search.py b/packages/views/search.py
index 6e892251..264e7bf6 100644
--- a/packages/views/search.py
+++ b/packages/views/search.py
@@ -1,6 +1,7 @@
import json
from django import forms
+from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.contrib.auth.models import User
from django.db.models import Q
from django.http import HttpResponse
@@ -14,6 +15,8 @@ from ..utils import attach_maintainers, PackageJSONEncoder
class PackageSearchForm(forms.Form):
+ limit = forms.CharField(required=False)
+ page = forms.CharField(required=False)
repo = forms.MultipleChoiceField(required=False)
arch = forms.MultipleChoiceField(required=False)
name = forms.CharField(required=False)
@@ -155,13 +158,29 @@ def search_json(request):
form = PackageSearchForm(data=request.GET,
show_staging=request.user.is_authenticated())
if form.is_valid():
+ form_limit = form.cleaned_data['limit']
+ limit = min(limit, int(form_limit)) if form_limit else limit
+ container['limit'] = limit
+
packages = Package.objects.select_related('arch', 'repo',
'packager')
if not request.user.is_authenticated():
packages = packages.filter(repo__staging=False)
- packages = parse_form(form, packages)[:limit]
- packages = packages.prefetch_related('groups', 'licenses',
- 'conflicts', 'provides', 'replaces', 'depends')
+ packages = parse_form(form, packages)
+
+ paginator = Paginator(packages, limit)
+ container['num_pages'] = paginator.num_pages
+
+ page = form.cleaned_data.get('page')
+ page = int(page) if page else 1
+ container['page'] = page
+ try:
+ packages = paginator.page(page)
+ except PageNotAnInteger:
+ packages = paginator.page(1)
+ except EmptyPage:
+ packages = paginator.page(paginator.num_pages)
+
attach_maintainers(packages)
container['results'] = packages
container['valid'] = True