From b6f1afa4f3ff72b737c510a23dac2b7fa04ace05 Mon Sep 17 00:00:00 2001 From: Magnus Hagander Date: Fri, 19 Jul 2013 18:48:37 +0200 Subject: [PATCH] Add basic filtering support --- pgcommitfest/commitfest/forms.py | 24 ++++++++++++- pgcommitfest/commitfest/models.py | 4 +-- .../commitfest/templates/commitfest.html | 30 ++++++++++++++++ pgcommitfest/commitfest/views.py | 34 +++++++++++++++++-- 4 files changed, 87 insertions(+), 5 deletions(-) diff --git a/pgcommitfest/commitfest/forms.py b/pgcommitfest/commitfest/forms.py index 9838ce6..8f2e33c 100644 --- a/pgcommitfest/commitfest/forms.py +++ b/pgcommitfest/commitfest/forms.py @@ -1,13 +1,35 @@ from django import forms from django.forms import ValidationError +from django.db.models import Q +from django.contrib.auth.models import User from selectable.forms.widgets import AutoCompleteSelectMultipleWidget -from models import Patch, MailThread +from models import Patch, MailThread, PatchOnCommitFest from lookups import UserLookup from widgets import ThreadPickWidget from ajax import _archivesAPI +class CommitFestFilterForm(forms.Form): + text = forms.CharField(max_length=50, required=False) + status = forms.ChoiceField(required=False) + author = forms.ChoiceField(required=False) + reviewer = forms.ChoiceField(required=False) + + def __init__(self, cf, *args, **kwargs): + super(CommitFestFilterForm, self).__init__(*args, **kwargs) + + c = [(-1, '* All')] + list(PatchOnCommitFest._STATUS_CHOICES) + self.fields['status'] = forms.ChoiceField(choices=c, required=False) + + q = Q(patch_author__commitfests=cf) | Q(patch_reviewer__commitfests=cf) + userchoices = [(-1, '* All'), (-2, '* None'), ] + [(u.id, '%s %s (%s)' % (u.first_name, u.last_name, u.username)) for u in User.objects.filter(q).distinct()] + self.fields['author'] = forms.ChoiceField(choices=userchoices, required=False) + self.fields['reviewer'] = forms.ChoiceField(choices=userchoices, required=False) + + for f in ('status', 'author', 'reviewer',): + self.fields[f].widget.attrs = {'class': 'input-medium'} + class PatchForm(forms.ModelForm): class Meta: model = Patch diff --git a/pgcommitfest/commitfest/models.py b/pgcommitfest/commitfest/models.py index 44dd884..e4326db 100644 --- a/pgcommitfest/commitfest/models.py +++ b/pgcommitfest/commitfest/models.py @@ -68,8 +68,8 @@ class Patch(models.Model): # Mailthreads are OneToMany in the other direction #mailthreads_set = ... - authors = models.ManyToManyField(User, related_name='author', blank=True) - reviewers = models.ManyToManyField(User, related_name='reviewer', blank=True) + authors = models.ManyToManyField(User, related_name='patch_author', blank=True) + reviewers = models.ManyToManyField(User, related_name='patch_reviewer', blank=True) committer = models.ForeignKey(Committer, blank=True, null=True) diff --git a/pgcommitfest/commitfest/templates/commitfest.html b/pgcommitfest/commitfest/templates/commitfest.html index 19f2739..946560b 100644 --- a/pgcommitfest/commitfest/templates/commitfest.html +++ b/pgcommitfest/commitfest/templates/commitfest.html @@ -1,6 +1,36 @@ {%extends "base.html"%} {%load commitfest %} {%block contents%} + +
+
+
+

Filters

+
+
+
+ + + +{%for f in form%} + +{%endfor%} + + + + + +{%for f in form%} + +{%endfor%} + + + +
{{f.label}}
{{f}}
+
+
+
+ {%for p in patches %} {%ifchanged p.is_open%} {%if not forloop.first%} diff --git a/pgcommitfest/commitfest/views.py b/pgcommitfest/commitfest/views.py index 5e77d6e..ede222e 100644 --- a/pgcommitfest/commitfest/views.py +++ b/pgcommitfest/commitfest/views.py @@ -2,6 +2,7 @@ from django.shortcuts import render_to_response, get_object_or_404 from django.http import HttpResponseRedirect, Http404 from django.template import RequestContext from django.db import transaction +from django.db.models import Q from django.contrib import messages from django.contrib.auth.decorators import login_required @@ -12,7 +13,7 @@ from email.utils import formatdate, make_msgid from mailqueue.util import send_mail from models import CommitFest, Patch, PatchOnCommitFest, PatchHistory, Committer -from forms import PatchForm, NewPatchForm, CommentForm +from forms import PatchForm, NewPatchForm, CommentForm, CommitFestFilterForm from ajax import doAttachThread def home(request): @@ -30,16 +31,45 @@ def home(request): def commitfest(request, cfid): # Find ourselves cf = get_object_or_404(CommitFest, pk=cfid) - patches = cf.patch_set.all().select_related().extra(select={ + + # Build a dynamic filter based on the filtering options entered + q = Q() + if request.GET.has_key('status') and request.GET['status'] != "-1": + q = q & Q(patchoncommitfest__status=int(request.GET['status'])) + if request.GET.has_key('author') and request.GET['author'] != "-1": + if request.GET['author'] == '-2': + q = q & Q(authors=None) + else: + q = q & Q(authors__id=int(request.GET['author'])) + if request.GET.has_key('reviewer') and request.GET['reviewer'] != "-1": + if request.GET['reviewer'] == '-2': + q = q & Q(reviewers=None) + else: + q = q & Q(reviewers__id=int(request.GET['reviewer'])) + + if request.GET.has_key('text') and request.GET['text'] != '': + q = q & Q(name__icontains=request.GET['text']) + + # Not sure if this is correct? + has_filter = len(q.children) > 0 + if not has_filter and request.GET: + # Redirect to get rid of the ugly url + return HttpResponseRedirect('/%s/' % cf.id) + + patches = cf.patch_set.filter(q).select_related().extra(select={ 'status':'commitfest_patchoncommitfest.status', 'author_names':"SELECT string_agg(first_name || ' ' || last_name || ' (' || username || ')', ', ') FROM auth_user INNER JOIN commitfest_patch_authors cpa ON cpa.user_id=auth_user.id WHERE cpa.patch_id=commitfest_patch.id", 'reviewer_names':"SELECT string_agg(first_name || ' ' || last_name || ' (' || username || ')', ', ') FROM auth_user INNER JOIN commitfest_patch_reviewers cpr ON cpr.user_id=auth_user.id WHERE cpr.patch_id=commitfest_patch.id", 'is_open':'commitfest_patchoncommitfest.status IN (%s)' % ','.join([str(x) for x in PatchOnCommitFest.OPEN_STATUSES]), }).order_by('-is_open', 'topic__topic', 'created') + form = CommitFestFilterForm(cf, request.GET) + return render_to_response('commitfest.html', { 'cf': cf, + 'form': form, 'patches': patches, + 'has_filter': has_filter, 'title': 'Commitfest %s' % cf.name, }, context_instance=RequestContext(request)) -- 2.39.5