admin.site.register(Topic)
admin.site.register(Patch, PatchAdmin)
admin.site.register(PatchHistory)
+admin.site.register(TargetVersion)
admin.site.register(MailThread)
admin.site.register(MailThreadAttachment, MailThreadAttachmentAdmin)
from selectable.forms.widgets import AutoCompleteSelectMultipleWidget
-from .models import Patch, MailThread, PatchOnCommitFest
+from .models import Patch, MailThread, PatchOnCommitFest, TargetVersion
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)
+ targetversion = forms.ChoiceField(required=False)
author = forms.ChoiceField(required=False)
reviewer = forms.ChoiceField(required=False)
sortkey = forms.IntegerField(required=False)
q = Q(patch_author__commitfests=cf) | Q(patch_reviewer__commitfests=cf)
userchoices = [(-1, '* All'), (-2, '* None'), (-3, '* Yourself')] + [(u.id, '%s %s (%s)' % (u.first_name, u.last_name, u.username)) for u in User.objects.filter(q).distinct().order_by('first_name', 'last_name')]
+ self.fields['targetversion'] = forms.ChoiceField(choices=[('-1', '* All'), ('-2', '* None')] + [(v.id, v.version) for v in TargetVersion.objects.all()], required=False, label="Target version")
self.fields['author'] = forms.ChoiceField(choices=userchoices, required=False)
self.fields['reviewer'] = forms.ChoiceField(choices=userchoices, required=False)
--- /dev/null
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.17 on 2019-02-06 19:43
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('commitfest', '0003_withdrawn_status'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='TargetVersion',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('version', models.CharField(max_length=8, unique=True)),
+ ],
+ options={
+ 'ordering': ['-version', ],
+ },
+ ),
+ migrations.AddField(
+ model_name='patch',
+ name='targetversion',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='commitfest.TargetVersion', verbose_name='Target version'),
+ ),
+ ]
return self.topic
+class TargetVersion(models.Model):
+ version = models.CharField(max_length=8, blank=False, null=False, unique=True)
+
+ class Meta:
+ ordering = ['-version', ]
+
+ def __str__(self):
+ return self.version
+
+
class Patch(models.Model, DiffableModel):
name = models.CharField(max_length=500, blank=False, null=False, verbose_name='Description')
topic = models.ForeignKey(Topic, blank=False, null=False)
# If there is a git repo about this patch
gitlink = models.URLField(blank=True, null=False, default='')
+ # Version targeted by this patch
+ targetversion = models.ForeignKey(TargetVersion, blank=True, null=True, verbose_name="Target version")
+
authors = models.ManyToManyField(User, related_name='patch_author', blank=True)
reviewers = models.ManyToManyField(User, related_name='patch_reviewer', blank=True)
<tr>
<th>{%if p.is_open%}<a href="#" style="color:#333333;" onclick="return sortpatches(0);">Patch</a>{%if sortkey == 0%}<div style="float:right;"><i class="glyphicon glyphicon-arrow-down"></i></div>{%endif%}{%endif%}</th>
<th>Status</th>
+ <th>Ver</th>
<th>Author</th>
<th>Reviewers</th>
<th>Committer</th>
<tr>
<td><a href="{{p.id}}/">{{p.name}}</a></td>
<td><span class="label label-{{p.status|patchstatuslabel}}">{{p.status|patchstatusstring}}</span></td>
+ <td>{%if p.targetversion%}<span class="label label-primary">{{p.targetversion}}</span>{%endif%}</td>
<td>{{p.author_names|default:''}}</td>
<td>{{p.reviewer_names|default:''}}</td>
<td>{{p.committer|default:''}}</td>
{%endfor%}
</td>
</tr>
+ <tr>
+ <th>Target version</th>
+ <td>{%if patch.targetversion%}<span class="label label-primary">{{patch.targetversion}}</span>{%endif%}
+ </tr>
<tr>
<th>Authors</th>
<td>{{patch.authors_string}}</td>
# int() failed -- so just ignore this filter
pass
+ if request.GET.get('targetversion', '-1') != '-1':
+ if request.GET['targetversion'] == '-2':
+ whereclauses.append("targetversion_id IS NULL")
+ else:
+ whereparams['verid'] = int(request.GET['targetversion'])
+ whereclauses.append("targetversion_id=%(verid)s")
+
if request.GET.get('author', '-1') != '-1':
if request.GET['author'] == '-2':
whereclauses.append("NOT EXISTS (SELECT 1 FROM commitfest_patch_authors cpa WHERE cpa.patch_id=p.id)")
# Let's not overload the poor django ORM
curs = connection.cursor()
- curs.execute("""SELECT p.id, p.name, poc.status, p.created, p.modified, p.lastmail, committer.username AS committer, t.topic,
+ curs.execute("""SELECT p.id, p.name, poc.status, v.version AS targetversion, p.created, p.modified, p.lastmail, committer.username AS committer, t.topic,
(poc.status=ANY(%(openstatuses)s)) AS is_open,
(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=p.id) AS author_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=p.id) AS reviewer_names,
INNER JOIN commitfest_patchoncommitfest poc ON poc.patch_id=p.id
INNER JOIN commitfest_topic t ON t.id=p.topic_id
LEFT JOIN auth_user committer ON committer.id=p.committer_id
+LEFT JOIN commitfest_targetversion v ON p.targetversion_id=v.id
WHERE poc.commitfest_id=%(cid)s {0}
-GROUP BY p.id, poc.id, committer.id, t.id
+GROUP BY p.id, poc.id, committer.id, t.id, v.version
ORDER BY is_open DESC, {1}""".format(where_str, orderby_str), params)
patches = [dict(zip([col[0] for col in curs.description], row)) for row in curs.fetchall()]