diff --git a/openslides/application/views.py b/openslides/application/views.py index 2d82fb9b2..b02e4f7dc 100644 --- a/openslides/application/views.py +++ b/openslides/application/views.py @@ -29,7 +29,7 @@ from reportlab.platypus import (SimpleDocTemplate, PageBreak, Paragraph, Spacer, from django.conf import settings from django.contrib import messages from django.contrib.auth.decorators import login_required -from django.contrib.auth.models import User, Group +from django.contrib.auth.models import User from django.core.context_processors import csrf from django.core.urlresolvers import reverse from django.db import transaction diff --git a/openslides/assignment/forms.py b/openslides/assignment/forms.py index 63768f0c2..2c4b6c7b9 100644 --- a/openslides/assignment/forms.py +++ b/openslides/assignment/forms.py @@ -11,35 +11,39 @@ """ from django import forms -from django.forms import ModelForm, Form, ModelChoiceField, Select +from django.utils.translation import ugettext_lazy as _, ugettext_noop from utils.forms import CssClassMixin -from utils.translation_ext import ugettext as _ + from participant.models import Profile from assignment.models import Assignment -class AssignmentForm(ModelForm, CssClassMixin): - posts = forms.IntegerField(min_value=1, label=_("Number of available posts")) +class AssignmentForm(forms.ModelForm, CssClassMixin): + posts = forms.IntegerField(min_value=1, + label=_("Number of available posts")) + class Meta: model = Assignment exclude = ('status', 'profile', 'elected') -class AssignmentRunForm(Form, CssClassMixin): - candidate = ModelChoiceField( - widget=Select(attrs={'class': 'medium-input'}), +class AssignmentRunForm(forms.Form, CssClassMixin): + candidate = forms.ModelChoiceField( + widget=forms.Select(attrs={'class': 'medium-input'}), queryset=Profile.objects.all().order_by('user__first_name'), label=_("Nominate a participant"), ) -class ConfigForm(Form, CssClassMixin): +class ConfigForm(forms.Form, CssClassMixin): assignment_publish_winner_results_only = forms.BooleanField( required=False, - label=_("Only publish voting results for selected winners (Projector view only)") + label=_("Only publish voting results for selected winners " + "(Projector view only)") ) - assignment_pdf_ballot_papers_selection = forms.ChoiceField(widget=forms.Select(), + assignment_pdf_ballot_papers_selection = forms.ChoiceField( + widget=forms.Select(), required=False, label=_("Number of ballot papers (selection)"), choices=( diff --git a/openslides/assignment/models.py b/openslides/assignment/models.py index 177544703..6d5b814ce 100644 --- a/openslides/assignment/models.py +++ b/openslides/assignment/models.py @@ -10,17 +10,21 @@ :license: GNU GPL, see LICENSE for more details. """ -from django.db import models from django.core.urlresolvers import reverse +from django.db import models +from django.dispatch import receiver +from django.utils.translation import ugettext_lazy as _, ugettext_noop -from config.models import config +from openslides.config.models import config +from openslides.config.signals import default_config_value -from participant.models import Profile +from openslides.projector.api import register_slidemodel +from openslides.projector.projector import SlideMixin -from projector.projector import SlideMixin -from projector.api import register_slidemodel -from poll.models import BasePoll, CountInvalid, CountVotesCast, BaseOption, PublishPollMixin -from utils.translation_ext import ugettext as _ +from openslides.participant.models import Profile + +from openslides.poll.models import (BasePoll, CountInvalid, CountVotesCast, + BaseOption, PublishPollMixin) from agenda.models import Item @@ -34,11 +38,15 @@ class Assignment(models.Model, SlideMixin): ) name = models.CharField(max_length=100, verbose_name=_("Name")) - description = models.TextField(null=True, blank=True, verbose_name=_("Description")) - posts = models.PositiveSmallIntegerField(verbose_name=_("Number of available posts")) - polldescription = models.CharField(max_length=100, null=True, blank=True, verbose_name=_("Short description (for ballot paper)")) - profile = models.ManyToManyField(Profile, null=True, blank=True) # Rename it in candidate - elected = models.ManyToManyField(Profile, null=True, blank=True, related_name='elected_set') + description = models.TextField(null=True, blank=True, + verbose_name=_("Description")) + posts = models.PositiveSmallIntegerField( + verbose_name=_("Number of available posts")) + polldescription = models.CharField(max_length=100, null=True, blank=True, + verbose_name=_("Short description (for ballot paper)")) + profile = models.ManyToManyField(Profile, null=True, blank=True) + elected = models.ManyToManyField(Profile, null=True, blank=True, + related_name='elected_set') status = models.CharField(max_length=3, choices=STATUS, default='sea') def set_status(self, status): @@ -50,7 +58,8 @@ class Assignment(models.Model, SlideMixin): if error: raise NameError(_('%s is not a valid status.') % status) if self.status == status: - raise NameError(_('The assignment status is already %s.') % self.status) + raise NameError(_('The assignment status is already %s.') + % self.status) self.status = status self.save() @@ -159,7 +168,8 @@ class Assignment(models.Model, SlideMixin): data['title'] = self.name data['polls'] = self.poll_set.filter(published=True) data['vote_results'] = self.vote_results(only_published=True) - data['assignment_publish_winner_results_only'] = config['assignment_publish_winner_results_only'] + data['assignment_publish_winner_results_only'] = \ + config['assignment_publish_winner_results_only'] data['template'] = 'projector/Assignment.html' return data @@ -176,10 +186,11 @@ class Assignment(models.Model, SlideMixin): class Meta: permissions = ( - ('can_see_assignment', _("Can see assignment", fixstr=True)), - ('can_nominate_other', _("Can nominate another person", fixstr=True)), - ('can_nominate_self', _("Can nominate themselves", fixstr=True)), - ('can_manage_assignment', _("Can manage assignment", fixstr=True)), + ('can_see_assignment', ugettext_noop("Can see assignment")), + ('can_nominate_other', + ugettext_noop("Can nominate another person")), + ('can_nominate_self', ugettext_noop("Can nominate themselves")), + ('can_manage_assignment', ugettext_noop("Can manage assignment")), ) register_slidemodel(Assignment) @@ -209,15 +220,16 @@ class AssignmentPoll(BasePoll, CountInvalid, CountVotesCast, PublishPollMixin): self.yesnoabstain = True else: # candidates <= available posts -> yes/no/abstain - if self.assignment.candidates.count() <= self.assignment.posts - self.assignment.elected.count(): + if self.assignment.candidates.count() <= (self.assignment.posts + - self.assignment.elected.count()): self.yesnoabstain = True else: self.yesnoabstain = False self.save() if self.yesnoabstain: - return [_('Yes', fixstr=True), _('No', fixstr=True), _('Abstain', fixstr=True)] + return [_('Yes'), _('No'), _('Abstain')] else: - return [_('Votes', fixstr=True)] + return [_('Votes')] def append_pollform_fields(self, fields): CountInvalid.append_pollform_fields(self, fields) @@ -237,8 +249,6 @@ class AssignmentPoll(BasePoll, CountInvalid, CountVotesCast, PublishPollMixin): return _("Ballot %d") % self.get_ballot() -from django.dispatch import receiver -from openslides.config.signals import default_config_value @receiver(default_config_value, dispatch_uid="assignment_default_config") diff --git a/openslides/assignment/urls.py b/openslides/assignment/urls.py index 1f072a2e1..e8887f101 100644 --- a/openslides/assignment/urls.py +++ b/openslides/assignment/urls.py @@ -10,7 +10,7 @@ :license: GNU GPL, see LICENSE for more details. """ -from django.conf.urls.defaults import * +from django.conf.urls.defaults import url, patterns from assignment.views import (ViewPoll, AssignmentPDF, AssignmentPollPDF, AssignmentPollDelete, CreateAgendaItem) @@ -21,41 +21,41 @@ urlpatterns = patterns('assignment.views', name='assignment_overview', ), - url(r'^(?P\d+)$', + url(r'^(?P\d+)/$', 'view', name='assignment_view'), - url(r'^new$', + url(r'^new/$', 'edit', name='assignment_new', ), - url(r'^(?P\d+)/edit$', + url(r'^(?P\d+)/edit/$', 'edit', name='assignment_edit', ), - url(r'^(?P\d+)/del$', + url(r'^(?P\d+)/del/$', 'delete', name='assignment_delete', ), - url(r'^(?P\d+)/setstatus/(?P[a-z]{3})$', + url(r'^(?P\d+)/setstatus/(?P[a-z]{3})/$', 'set_status', name='assignment_set_status', ), - url(r'^(?P\d+)/run$', + url(r'^(?P\d+)/run/$', 'run', name='assignment_run', ), - url(r'^(?P\d+)/delrun$', + url(r'^(?P\d+)/delrun/$', 'delrun', name='assignment_delrun', ), - url(r'^(?P\d+)/delother/(?P\d+)$', + url(r'^(?P\d+)/delother/(?P\d+)/$', 'delother', name='assignment_delother', ), @@ -80,22 +80,22 @@ urlpatterns = patterns('assignment.views', name='print_assignment', ), - url(r'^(?P\d+)/print$', + url(r'^(?P\d+)/print/$', AssignmentPDF.as_view(), name='print_assignment', ), - url(r'^(?P\d+)/gen_poll$', + url(r'^(?P\d+)/gen_poll/$', 'gen_poll', name='assignment_gen_poll', ), - url(r'^poll/(?P\d+)$', + url(r'^poll/(?P\d+)/$', ViewPoll.as_view(), name='assignment_poll_view', ), - url(r'^poll/(?P\d+)/del$', + url(r'^poll/(?P\d+)/del/$', AssignmentPollDelete.as_view(), name='assignment_poll_delete', ), @@ -105,13 +105,13 @@ urlpatterns = patterns('assignment.views', name='assignment_poll_publish_status', ), - url(r'^(?P\d+)/elected/(?P\d+)$', + url(r'^(?P\d+)/elected/(?P\d+)/$', 'set_elected', {'elected': True}, name='assignment_user_elected', ), - url(r'^(?P\d+)/notelected/(?P\d+)$', + url(r'^(?P\d+)/notelected/(?P\d+)/$', 'set_elected', {'elected': False}, name='assignment_user_not_elected', diff --git a/openslides/assignment/views.py b/openslides/assignment/views.py index 983d06fd2..7f1532f5e 100644 --- a/openslides/assignment/views.py +++ b/openslides/assignment/views.py @@ -13,35 +13,37 @@ import os from reportlab.lib import colors +from reportlab.platypus import (SimpleDocTemplate, PageBreak, Paragraph, + Spacer, Table, TableStyle) from reportlab.lib.units import cm -from reportlab.platypus import SimpleDocTemplate, PageBreak, Paragraph, Spacer, Table, TableStyle -from django.shortcuts import redirect +from django.conf import settings from django.core.urlresolvers import reverse from django.contrib import messages from django.contrib.auth.decorators import login_required from django.contrib.auth.models import User -from django.utils.translation import ungettext, ugettext as _ +from django.shortcuts import redirect +from django.utils.translation import ungettext, ugettext_lazy as _ -from config.models import config -from settings import SITE_ROOT - -from utils.utils import template, permission_required, gen_confirm_form, del_confirm_form, ajax_request from utils.pdf import stylesheet -from utils.views import FormView, DeleteView, PDFView, RedirectView from utils.template import Tab -from utils.translation_ext import ugettext +from utils.utils import (template, permission_required, gen_confirm_form, + del_confirm_form, ajax_request) +from utils.views import FormView, DeleteView, PDFView, RedirectView -from projector.projector import Widget +from openslides.config.models import config +from openslides.participant.models import Profile -from poll.views import PollFormView +from openslides.projector.projector import Widget -from agenda.models import Item +from openslides.poll.views import PollFormView -from assignment.models import Assignment, AssignmentPoll, AssignmentOption -from assignment.forms import AssignmentForm, AssignmentRunForm, ConfigForm +from openslides.agenda.models import Item -from participant.models import Profile +from openslides.assignment.models import (Assignment, AssignmentPoll, + AssignmentOption) +from openslides.assignment.forms import (AssignmentForm, AssignmentRunForm, + ConfigForm) @permission_required('assignment.can_see_assignment') @@ -307,7 +309,8 @@ class AssignmentPDF(PDFView): try: assignment_id = self.kwargs['assignment_id'] assignment = Assignment.objects.get(id=assignment_id) - filename = u'%s-%s' % (_("Assignment"), assignment.name.replace(' ','_')) + filename = u'%s-%s' % (_("Assignment"), + assignment.name.replace(' ','_')) except: filename = _("Elections") return filename @@ -322,15 +325,18 @@ class AssignmentPDF(PDFView): story.append(Paragraph(title, stylesheet['Heading1'])) preamble = config["assignment_pdf_preamble"] if preamble: - story.append(Paragraph("%s" % preamble.replace('\r\n','
'), stylesheet['Paragraph'])) + story.append(Paragraph("%s" % preamble.replace('\r\n','
'), + stylesheet['Paragraph'])) story.append(Spacer(0,0.75*cm)) assignments = Assignment.objects.order_by('name') if not assignments: # No assignments existing - story.append(Paragraph(_("No assignments available."), stylesheet['Heading3'])) + story.append(Paragraph(_("No assignments available."), + stylesheet['Heading3'])) else: # Print all assignments # List of assignments for assignment in assignments: - story.append(Paragraph(assignment.name, stylesheet['Heading3'])) + story.append(Paragraph(assignment.name, + stylesheet['Heading3'])) # Assignment details (each assignment on single page) for assignment in assignments: story.append(PageBreak()) @@ -343,22 +349,28 @@ class AssignmentPDF(PDFView): def get_assignment(self, assignment, story): # title - story.append(Paragraph(_("Election")+": %s" % assignment.name, stylesheet['Heading1'])) + story.append(Paragraph(_("Election")+": %s" % assignment.name, + stylesheet['Heading1'])) story.append(Spacer(0,0.5*cm)) # posts cell1a = [] - cell1a.append(Paragraph("%s:" % _("Number of available posts"), stylesheet['Bold'])) + cell1a.append(Paragraph("%s:" % + _("Number of available posts"), stylesheet['Bold'])) cell1b = [] cell1b.append(Paragraph(str(assignment.posts), stylesheet['Paragraph'])) # candidates cell2a = [] - cell2a.append(Paragraph("%s:" % _("Candidates"), stylesheet['Heading4'])) + cell2a.append(Paragraph("%s:" % _("Candidates"), stylesheet['Heading4'])) cell2b = [] - for c in assignment.profile.all(): - cell2b.append(Paragraph(".  %s" % unicode(c), stylesheet['Signaturefield'])) + for candidate in assignment.profile.all(): + cell2b.append(Paragraph(".  %s" % candidate, + stylesheet['Signaturefield'])) if assignment.status == "sea": for x in range(0, 2 * assignment.posts): - cell2b.append(Paragraph(".  __________________________________________",stylesheet['Signaturefield'])) + cell2b.append(Paragraph(".  " + "__________________________________________", + stylesheet['Signaturefield'])) cell2b.append(Spacer(0,0.2*cm)) # Vote results @@ -371,12 +383,15 @@ class AssignmentPDF(PDFView): # Left side cell3a = [] - cell3a.append(Paragraph("%s:" % (_("Vote results")), stylesheet['Heading4'])) + cell3a.append(Paragraph("%s:" % (_("Vote results")), + stylesheet['Heading4'])) if polls.count() == 1: - cell3a.append(Paragraph("%s %s" % (polls.count(), _("ballot")), stylesheet['Normal'])) + cell3a.append(Paragraph("%s %s" % (polls.count(), _("ballot")), + stylesheet['Normal'])) elif polls.count() > 1: - cell3a.append(Paragraph("%s %s" % (polls.count(), _("ballots")), stylesheet['Normal'])) + cell3a.append(Paragraph("%s %s" % (polls.count(), _("ballots")), + stylesheet['Normal'])) # Add table head row headrow = [] @@ -443,18 +458,19 @@ class AssignmentPDF(PDFView): data.append(['', '* = '+_('elected')]) else: data.append([cell2a, cell2b]) - data.append([Spacer(0,0.2*cm),'']) + data.append([Spacer(0, 0.2 * cm), '']) t=Table(data) - t._argW[0]=4.5*cm - t._argW[1]=11*cm - t.setStyle(TableStyle([ ('BOX', (0,0), (-1,-1), 1, colors.black), - ('VALIGN', (0,0), (-1,-1), 'TOP'), - ])) + t._argW[0] = 4.5 * cm + t._argW[1] = 11 * cm + t.setStyle(TableStyle([ ('BOX', (0,0), (-1, -1), 1, colors.black), + ('VALIGN', (0, 0), (-1, -1), 'TOP'), + ])) story.append(t) - story.append(Spacer(0,1*cm)) + story.append(Spacer(0, 1 * cm)) # text - story.append(Paragraph("%s" % assignment.description.replace('\r\n','
'), stylesheet['Paragraph'])) + story.append(Paragraph("%s" % assignment.description.replace('\r\n', + '
'), stylesheet['Paragraph'])) class CreateAgendaItem(RedirectView): @@ -478,25 +494,35 @@ class AssignmentPollPDF(PDFView): return super(AssignmentPollPDF, self).get(request, *args, **kwargs) def get_filename(self): - filename = u'%s-%s-#%s' % (_("Election"), self.poll.assignment.name.replace(' ','_'), 1)#self.poll.get_ballot()) + filename = u'%s-%s-#%s' % (_("Election"), self.poll.assignment.name + .replace(' ', '_'), 1) return filename def get_template(self, buffer): - return SimpleDocTemplate(buffer, topMargin=-6, bottomMargin=-6, leftMargin=0, rightMargin=0, showBoundary=False) + return SimpleDocTemplate(buffer, topMargin=-6, bottomMargin=-6, + leftMargin=0, rightMargin=0, showBoundary=False) def build_document(self, pdf_document, story): pdf_document.build(story) def append_to_pdf(self, story): - imgpath = os.path.join(SITE_ROOT, 'static/images/circle.png') + imgpath = os.path.join(settings.SITE_ROOT, 'static/images/circle.png') circle = "  " % imgpath cell = [] cell.append(Spacer(0,0.8*cm)) - cell.append(Paragraph(_("Election") + ": " + self.poll.assignment.name, stylesheet['Ballot_title'])) - cell.append(Paragraph(self.poll.assignment.polldescription, stylesheet['Ballot_subtitle'])) + cell.append(Paragraph(_("Election") + ": " + self.poll.assignment.name, + stylesheet['Ballot_title'])) + cell.append(Paragraph(self.poll.assignment.polldescription, + stylesheet['Ballot_subtitle'])) options = self.poll.get_options().order_by('candidate') - cell.append(Paragraph(str(self.poll.get_ballot())+". "+_("ballot")+", "+str(len(options))+" "+ ungettext("candidate", "candidates", len(options))+", "+str(self.poll.assignment.posts)+" "+_("available posts"), stylesheet['Ballot_description'])) - cell.append(Spacer(0,0.4*cm)) + + ballot_string = _("%d. ballot") % self.poll.get_ballot() + candidate_string = ungettext("%d candidate", "%d candidates", + len(options)) % len(options) + available_posts_string = _("%d available posts") % self.poll.assignment.posts + cell.append(Paragraph("%s, %s, %s" % (ballot_string, candidate_string, + available_posts_string), stylesheet['Ballot_description'])) + cell.append(Spacer(0, 0.4 * cm)) data= [] # get ballot papers config values @@ -516,12 +542,17 @@ class AssignmentPollPDF(PDFView): if self.poll.yesnoabstain: for option in options: candidate = option.candidate - cell.append(Paragraph(candidate.user.get_full_name(), stylesheet['Ballot_option_name'])) + cell.append(Paragraph(candidate.user.get_full_name(), + stylesheet['Ballot_option_name'])) if candidate.group: - cell.append(Paragraph("(%s)" % candidate.group, stylesheet['Ballot_option_group'])) + cell.append(Paragraph("(%s)" % candidate.group, + stylesheet['Ballot_option_group'])) else: - cell.append(Paragraph(" ", stylesheet['Ballot_option_group'])) - cell.append(Paragraph(circle+_("Yes")+"      "+circle+_("No")+"      "+circle+_("Abstention"), stylesheet['Ballot_option_YNA'])) + cell.append(Paragraph(" ", + stylesheet['Ballot_option_group'])) + cell.append(Paragraph(circle + _("Yes") + "  " * 3 + circle + + _("No") + "  " * 3 + circle+ _("Abstention"), + stylesheet['Ballot_option_YNA'])) # print ballot papers for user in xrange(number / 2): data.append([cell, cell]) @@ -529,19 +560,22 @@ class AssignmentPollPDF(PDFView): if rest: data.append([cell, '']) if len(options) <= 2: - t = Table(data, 10.5*cm, 7.42*cm) + t = Table(data, 10.5 * cm, 7.42 * cm) elif len(options) <= 5: - t = Table(data, 10.5*cm, 14.84*cm) + t = Table(data, 10.5 * cm, 14.84 * cm) else: - t = Table(data, 10.5*cm, 29.7*cm) + t = Table(data, 10.5 * cm, 29.7 * cm) else: for option in options: candidate = option.candidate - cell.append(Paragraph(circle + candidate.user.get_full_name(), stylesheet['Ballot_option_name'])) + cell.append(Paragraph(circle + candidate.user.get_full_name(), + stylesheet['Ballot_option_name'])) if candidate.group: - cell.append(Paragraph("(%s)" % candidate.group, stylesheet['Ballot_option_group_right'])) + cell.append(Paragraph("(%s)" % candidate.group, + stylesheet['Ballot_option_group_right'])) else: - cell.append(Paragraph(" ", stylesheet['Ballot_option_group_right'])) + cell.append(Paragraph(" ", + stylesheet['Ballot_option_group_right'])) # print ballot papers for user in xrange(number / 2): data.append([cell, cell]) @@ -549,15 +583,15 @@ class AssignmentPollPDF(PDFView): if rest: data.append([cell, '']) if len(options) <= 4: - t = Table(data, 10.5*cm, 7.42*cm) + t = Table(data, 10.5 * cm, 7.42 * cm) elif len(options) <= 8: - t = Table(data, 10.5*cm, 14.84*cm) + t = Table(data, 10.5 * cm, 14.84 * cm) else: - t = Table(data, 10.5*cm, 29.7*cm) + t = Table(data, 10.5 * cm, 29.7 * cm) - t.setStyle(TableStyle([ ('GRID', (0,0), (-1,-1), 0.25, colors.grey), - ('VALIGN', (0,0), (-1,-1), 'TOP'), - ])) + t.setStyle(TableStyle([('GRID', (0, 0), (-1, -1), 0.25, colors.grey), + ('VALIGN', (0, 0), (-1, -1), 'TOP'), + ])) story.append(t) @@ -568,12 +602,16 @@ class Config(FormView): def get_initial(self): return { - 'assignment_publish_winner_results_only': config['assignment_publish_winner_results_only'], - 'assignment_pdf_ballot_papers_selection': config['assignment_pdf_ballot_papers_selection'], - 'assignment_pdf_ballot_papers_number': config['assignment_pdf_ballot_papers_number'], + 'assignment_publish_winner_results_only': + config['assignment_publish_winner_results_only'], + 'assignment_pdf_ballot_papers_selection': + config['assignment_pdf_ballot_papers_selection'], + 'assignment_pdf_ballot_papers_number': + config['assignment_pdf_ballot_papers_number'], 'assignment_pdf_title': config['assignment_pdf_title'], 'assignment_pdf_preamble': config['assignment_pdf_preamble'], - 'assignment_poll_vote_values': config['assignment_poll_vote_values'], + 'assignment_poll_vote_values': + config['assignment_poll_vote_values'], } def form_valid(self, form): @@ -581,21 +619,30 @@ class Config(FormView): config['assignment_publish_winner_results_only'] = True else: config['assignment_publish_winner_results_only'] = False - config['assignment_pdf_ballot_papers_selection'] = form.cleaned_data['assignment_pdf_ballot_papers_selection'] - config['assignment_pdf_ballot_papers_number'] = form.cleaned_data['assignment_pdf_ballot_papers_number'] - config['assignment_pdf_title'] = form.cleaned_data['assignment_pdf_title'] - config['assignment_pdf_preamble'] = form.cleaned_data['assignment_pdf_preamble'] - config['assignment_poll_vote_values'] = form.cleaned_data['assignment_poll_vote_values'] - messages.success(self.request, _('Election settings successfully saved.')) + config['assignment_pdf_ballot_papers_selection'] = \ + form.cleaned_data['assignment_pdf_ballot_papers_selection'] + config['assignment_pdf_ballot_papers_number'] = \ + form.cleaned_data['assignment_pdf_ballot_papers_number'] + config['assignment_pdf_title'] = \ + form.cleaned_data['assignment_pdf_title'] + config['assignment_pdf_preamble'] = \ + form.cleaned_data['assignment_pdf_preamble'] + config['assignment_poll_vote_values'] = \ + form.cleaned_data['assignment_poll_vote_values'] + messages.success(self.request, + _('Election settings successfully saved.')) return super(Config, self).form_valid(form) def register_tab(request): - selected = True if request.path.startswith('/assignment/') else False + selected = request.path.startswith('/assignment/') return Tab( title=_('Elections'), url=reverse('assignment_overview'), - permission=request.user.has_perm('assignment.can_see_assignment') or request.user.has_perm('assignment.can_nominate_other') or request.user.has_perm('assignment.can_nominate_self') or request.user.has_perm('assignment.can_manage_assignment'), + permission=request.user.has_perm('assignment.can_see_assignment') + or request.user.has_perm('assignment.can_nominate_other') + or request.user.has_perm('assignment.can_nominate_self') + or request.user.has_perm('assignment.can_manage_assignment'), selected=selected, )