Skip to content

Commit 4fec101

Browse files
committed
Feedback refactor:
* Now Feedback have manytomany to posotions, so a feedback email can be associated to few positions. * Add user and time field to nomination model * Delete feedbacks and questionnaires field from nomineeposition model, now feedback model has all information about nominations, feedback and quiestionnaires * Add user field to Feedback model to know the nomcom meber who made the nomination, regardless of the real author * Add nomcom field to Feedback and refactor EncryptedTextField, it's necessary to encrypt the comments with the nomcom public key. * Template tag to decrypt feedback has been improved, now It isn't necessary the view context has the private key variable. * Add skel view to view feedback * Delete hidden fields from private and public feedback form * Refactor private index view to show total number of questionnaires and to show if the nomienee has questionnaires or not See ietf-tools#970 - Legacy-Id: 5571
1 parent b1f1ceb commit 4fec101

12 files changed

Lines changed: 151 additions & 134 deletions

File tree

ietf/nomcom/admin.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class PositionAdmin(admin.ModelAdmin):
2828

2929

3030
class FeedbackAdmin(admin.ModelAdmin):
31-
list_display = ('nominee', 'author', 'position', 'type')
31+
list_display = ('nominee', 'author', 'type')
3232
list_filter = ('type',)
3333

3434
admin.site.register(NomCom, NomComAdmin)

ietf/nomcom/fields.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ class EncryptedTextField(models.TextField):
1515
def pre_save(self, instance, add):
1616
if add:
1717
comments = getattr(instance, 'comments')
18-
position = getattr(instance, 'position')
19-
cert_file = position.nomcom.public_key.path
18+
nomcom = getattr(instance, 'nomcom')
19+
cert_file = nomcom.public_key.path
2020
comments_file = tempfile.NamedTemporaryFile(delete=False)
2121
comments_file.write(comments)
2222
comments_file.close()

ietf/nomcom/forms.py

Lines changed: 16 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -302,8 +302,7 @@ def __init__(self, *args, **kwargs):
302302

303303
super(NominateForm, self).__init__(*args, **kwargs)
304304

305-
fieldset = ['nominator_email',
306-
'position',
305+
fieldset = ['position',
307306
'candidate_name',
308307
'candidate_email', 'candidate_phone',
309308
'comments']
@@ -312,6 +311,7 @@ def __init__(self, *args, **kwargs):
312311
self.fields['position'].queryset = Position.objects.get_by_nomcom(self.nomcom).opened()
313312

314313
if not self.public:
314+
fieldset = ['nominator_email'] + fieldset
315315
author = get_user_email(self.user)
316316
if author:
317317
self.fields['nominator_email'].initial = author.address
@@ -350,10 +350,11 @@ def save(self, commit=True):
350350
nominee_position, nominee_position_created = NomineePosition.objects.get_or_create(position=position, nominee=nominee)
351351

352352
# Complete nomination data
353-
feedback = Feedback.objects.create(position=position,
353+
feedback = Feedback.objects.create(nomcom=self.nomcom,
354354
nominee=nominee,
355355
comments=comments,
356356
type=FeedbackType.objects.get(slug='nomina'))
357+
feedback.positions.add(position)
357358
author = None
358359
if self.public:
359360
author = get_user_email(self.user)
@@ -369,6 +370,7 @@ def save(self, commit=True):
369370

370371
nomination.nominee = nominee
371372
nomination.comments = feedback
373+
nomination.user = self.user
372374

373375
if commit:
374376
nomination.save()
@@ -480,10 +482,7 @@ def __init__(self, *args, **kwargs):
480482
'nominee_email',
481483
'nominator_name',
482484
'nominator_email',
483-
'comments',
484-
'position',
485-
'type',
486-
'nominee']
485+
'comments']
487486

488487
if self.public:
489488
readonly_fields += ['nominator_name', 'nominator_email']
@@ -494,18 +493,13 @@ def __init__(self, *args, **kwargs):
494493
and the address will also be captured as part of the registered nomination.)"""
495494
self.fields['nominator_email'].help_text = help_text
496495

497-
hidden_fields = ['position', 'type', 'nominee']
498-
499496
author = get_user_email(self.user)
500497
if author:
501498
self.fields['nominator_email'].initial = author.address
502499
self.fields['nominator_name'].initial = author.person.name
503500

504501
if self.position and self.nominee:
505-
self.fields['type'].initial = "comment"
506-
self.fields['position'].initial = self.position
507502
self.fields['position_name'].initial = self.position.name
508-
self.fields['nominee'].initial = self.nominee
509503
self.fields['nominee_name'].initial = self.nominee.email.person.name
510504
self.fields['nominee_email'].initial = self.nominee.email.address
511505
else:
@@ -520,16 +514,11 @@ def __init__(self, *args, **kwargs):
520514
for field in readonly_fields:
521515
self.fields[field].widget.attrs['readonly'] = True
522516

523-
for field in hidden_fields:
524-
self.fields[field].widget = forms.HiddenInput()
525-
526517
self.fieldsets = [('Provide comments', fieldset)]
527518

528519
def save(self, commit=True):
529520
feedback = super(FeedbackForm, self).save(commit=False)
530521
confirmation = self.cleaned_data['confirmation']
531-
nominee = self.cleaned_data['nominee']
532-
position = self.cleaned_data['position']
533522
comments = self.cleaned_data['comments']
534523
nominator_email = self.cleaned_data['nominator_email']
535524
nomcom_template_path = '/nomcom/%s/' % self.nomcom.group.acronym
@@ -544,32 +533,35 @@ def save(self, commit=True):
544533

545534
if author:
546535
feedback.author = author
547-
feedback.save()
536+
537+
feedback.nomcom = self.nomcom
538+
feedback.nominee = self.nominee
539+
feedback.user = self.user
540+
feedback.type = FeedbackType.objects.get(slug='comment')
541+
feedback.save()
542+
feedback.positions.add(self.position)
548543

549544
# send receipt email to feedback author
550545
if confirmation or not self.public:
551546
if author:
552547
subject = "NomCom comment confirmation"
553548
from_email = settings.NOMCOM_FROM_EMAIL
554549
to_email = author.address
555-
context = {'nominee': nominee.email.person.name,
550+
context = {'nominee': self.nominee.email.person.name,
556551
'comments': comments,
557-
'position': position.name}
552+
'position': self.position.name}
558553
path = nomcom_template_path + FEEDBACK_RECEIPT_TEMPLATE
559554
send_mail(None, to_email, from_email, subject, path, context)
560555

561556
class Meta:
562557
model = Feedback
563558
fields = ('author',
564-
'position',
565-
'nominee',
566559
'nominee_name',
567560
'nominee_email',
568561
'nominator_name',
569562
'nominator_email',
570563
'confirmation',
571-
'comments',
572-
'type')
564+
'comments')
573565

574566
class Media:
575567
js = ("/js/jquery-1.5.1.min.js",

ietf/nomcom/migrations/0001_initial.py

Lines changed: 23 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ def forwards(self, orm):
2727
('nominee', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['nomcom.Nominee'])),
2828
('comments', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['nomcom.Feedback'])),
2929
('nominator_email', self.gf('django.db.models.fields.EmailField')(max_length=75, blank=True)),
30+
('user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'])),
31+
('time', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)),
3032
))
3133
db.send_create_signal('nomcom', ['Nomination'])
3234

@@ -51,22 +53,6 @@ def forwards(self, orm):
5153
# Adding unique constraint on 'NomineePosition', fields ['position', 'nominee']
5254
db.create_unique('nomcom_nomineeposition', ['position_id', 'nominee_id'])
5355

54-
# Adding M2M table for field questionnaires on 'NomineePosition'
55-
db.create_table('nomcom_nomineeposition_questionnaires', (
56-
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
57-
('nomineeposition', models.ForeignKey(orm['nomcom.nomineeposition'], null=False)),
58-
('feedback', models.ForeignKey(orm['nomcom.feedback'], null=False))
59-
))
60-
db.create_unique('nomcom_nomineeposition_questionnaires', ['nomineeposition_id', 'feedback_id'])
61-
62-
# Adding M2M table for field feedback on 'NomineePosition'
63-
db.create_table('nomcom_nomineeposition_feedback', (
64-
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
65-
('nomineeposition', models.ForeignKey(orm['nomcom.nomineeposition'], null=False)),
66-
('feedback', models.ForeignKey(orm['nomcom.feedback'], null=False))
67-
))
68-
db.create_unique('nomcom_nomineeposition_feedback', ['nomineeposition_id', 'feedback_id'])
69-
7056
# Adding model 'Position'
7157
db.create_table('nomcom_position', (
7258
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
@@ -84,15 +70,24 @@ def forwards(self, orm):
8470
# Adding model 'Feedback'
8571
db.create_table('nomcom_feedback', (
8672
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
73+
('nomcom', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['nomcom.NomCom'])),
8774
('author', self.gf('django.db.models.fields.EmailField')(max_length=75, blank=True)),
88-
('position', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['nomcom.Position'])),
8975
('nominee', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['nomcom.Nominee'])),
9076
('comments', self.gf('ietf.nomcom.fields.EncryptedTextField')()),
9177
('type', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['name.FeedbackType'])),
78+
('user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'], null=True, blank=True)),
9279
('time', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)),
9380
))
9481
db.send_create_signal('nomcom', ['Feedback'])
9582

83+
# Adding M2M table for field positions on 'Feedback'
84+
db.create_table('nomcom_feedback_positions', (
85+
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
86+
('feedback', models.ForeignKey(orm['nomcom.feedback'], null=False)),
87+
('position', models.ForeignKey(orm['nomcom.position'], null=False))
88+
))
89+
db.create_unique('nomcom_feedback_positions', ['feedback_id', 'position_id'])
90+
9691

9792
def backwards(self, orm):
9893

@@ -111,18 +106,15 @@ def backwards(self, orm):
111106
# Deleting model 'NomineePosition'
112107
db.delete_table('nomcom_nomineeposition')
113108

114-
# Removing M2M table for field questionnaires on 'NomineePosition'
115-
db.delete_table('nomcom_nomineeposition_questionnaires')
116-
117-
# Removing M2M table for field feedback on 'NomineePosition'
118-
db.delete_table('nomcom_nomineeposition_feedback')
119-
120109
# Deleting model 'Position'
121110
db.delete_table('nomcom_position')
122111

123112
# Deleting model 'Feedback'
124113
db.delete_table('nomcom_feedback')
125114

115+
# Removing M2M table for field positions on 'Feedback'
116+
db.delete_table('nomcom_feedback_positions')
117+
126118

127119
models = {
128120
'auth.group': {
@@ -344,10 +336,12 @@ def backwards(self, orm):
344336
'author': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
345337
'comments': ('ietf.nomcom.fields.EncryptedTextField', [], {}),
346338
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
339+
'nomcom': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['nomcom.NomCom']"}),
347340
'nominee': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['nomcom.Nominee']"}),
348-
'position': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['nomcom.Position']"}),
341+
'positions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['nomcom.Position']", 'null': 'True', 'blank': 'True'}),
349342
'time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
350-
'type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.FeedbackType']"})
343+
'type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.FeedbackType']"}),
344+
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
351345
},
352346
'nomcom.nomcom': {
353347
'Meta': {'object_name': 'NomCom'},
@@ -365,7 +359,9 @@ def backwards(self, orm):
365359
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
366360
'nominator_email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
367361
'nominee': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['nomcom.Nominee']"}),
368-
'position': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['nomcom.Position']"})
362+
'position': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['nomcom.Position']"}),
363+
'time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
364+
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
369365
},
370366
'nomcom.nominee': {
371367
'Meta': {'object_name': 'Nominee'},
@@ -375,12 +371,10 @@ def backwards(self, orm):
375371
'nominee_position': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['nomcom.Position']", 'through': "orm['nomcom.NomineePosition']", 'symmetrical': 'False'})
376372
},
377373
'nomcom.nomineeposition': {
378-
'Meta': {'unique_together': "(('position', 'nominee'),)", 'object_name': 'NomineePosition'},
379-
'feedback': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['nomcom.Feedback']", 'null': 'True', 'blank': 'True'}),
374+
'Meta': {'ordering': "['nominee']", 'unique_together': "(('position', 'nominee'),)", 'object_name': 'NomineePosition'},
380375
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
381376
'nominee': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['nomcom.Nominee']"}),
382377
'position': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['nomcom.Position']"}),
383-
'questionnaires': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'questionnaires'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['nomcom.Feedback']"}),
384378
'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.NomineePositionState']"}),
385379
'time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'})
386380
},

ietf/nomcom/models.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from django.db import models
44
from django.conf import settings
55
from django.core.files.storage import FileSystemStorage
6+
from django.contrib.auth.models import User
67

78
from south.modelsinspector import add_introspection_rules
89

@@ -52,6 +53,8 @@ class Nomination(models.Model):
5253
nominee = models.ForeignKey('Nominee')
5354
comments = models.ForeignKey('Feedback')
5455
nominator_email = models.EmailField(verbose_name='Nominator Email', blank=True)
56+
user = models.ForeignKey(User)
57+
time = models.DateTimeField(auto_now_add=True)
5558

5659
class Meta:
5760
verbose_name_plural = 'Nominations'
@@ -80,10 +83,6 @@ class NomineePosition(models.Model):
8083
position = models.ForeignKey('Position')
8184
nominee = models.ForeignKey('Nominee')
8285
state = models.ForeignKey(NomineePositionState)
83-
questionnaires = models.ManyToManyField('Feedback',
84-
related_name='questionnaires',
85-
blank=True, null=True)
86-
feedback = models.ManyToManyField('Feedback', blank=True, null=True)
8786
time = models.DateTimeField(auto_now_add=True)
8887

8988
objects = NomineePositionManager()
@@ -102,6 +101,12 @@ def save(self, **kwargs):
102101
def __unicode__(self):
103102
return u"%s - %s" % (self.nominee, self.position)
104103

104+
@property
105+
def questionnaires(self):
106+
return Feedback.objects.filter(type='questio',
107+
positions=self.position,
108+
nominee=self.nominee)
109+
105110

106111
class Position(models.Model):
107112
nomcom = models.ForeignKey('NomCom')
@@ -144,11 +149,13 @@ def get_templates(self):
144149

145150

146151
class Feedback(models.Model):
152+
nomcom = models.ForeignKey('NomCom')
147153
author = models.EmailField(verbose_name='Author', blank=True)
148-
position = models.ForeignKey('Position')
154+
positions = models.ManyToManyField('Position', blank=True, null=True)
149155
nominee = models.ForeignKey('Nominee')
150156
comments = EncryptedTextField(verbose_name='Comments')
151157
type = models.ForeignKey(FeedbackType)
158+
user = models.ForeignKey(User, blank=True, null=True)
152159
time = models.DateTimeField(auto_now_add=True)
153160

154161
def __unicode__(self):

ietf/nomcom/templatetags/nomcom_tags.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from ietf.ietfauth.decorators import has_role
99

1010
from ietf.nomcom.models import Feedback
11-
from ietf.nomcom.utils import get_nomcom_by_year, get_user_email
11+
from ietf.nomcom.utils import get_nomcom_by_year, get_user_email, retrieve_nomcom_private_key
1212

1313

1414
register = template.Library()
@@ -27,7 +27,8 @@ def is_chair(user, year):
2727
@register.simple_tag
2828
def add_num_nominations(user, position, nominee):
2929
author = get_user_email(user)
30-
count = Feedback.objects.filter(position=position,
30+
31+
count = Feedback.objects.filter(positions__in=[position],
3132
nominee=nominee,
3233
author=author,
3334
type='comment').count()
@@ -39,8 +40,10 @@ def add_num_nominations(user, position, nominee):
3940
return '<span title="%d earlier comments from you on %s as %s">%s</span>&nbsp;' % (count, nominee, position, mark)
4041

4142

42-
@register.filter
43-
def decrypt(string, key=None):
43+
@register.simple_tag
44+
def decrypt(string, request, year):
45+
key = retrieve_nomcom_private_key(request, year)
46+
4447
if not key:
4548
return '<-Encripted text [No private key provided]->'
4649

0 commit comments

Comments
 (0)