Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# (c) 2018-2020
2# MPIB <https://www.mpib-berlin.mpg.de/>,
3# MPI-CBS <https://www.cbs.mpg.de/>,
4# MPIP <http://www.psych.mpg.de/>
5#
6# This file is part of Castellum.
7#
8# Castellum is free software; you can redistribute it and/or modify it
9# under the terms of the GNU Affero General Public License as published
10# by the Free Software Foundation; either version 3 of the License, or
11# (at your option) any later version.
12#
13# Castellum is distributed in the hope that it will be useful, but
14# WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16# Affero General Public License for more details.
17#
18# You should have received a copy of the GNU Affero General Public
19# License along with Castellum. If not, see
20# <http://www.gnu.org/licenses/>.
22from django.http import HttpResponseBadRequest
23from django.shortcuts import get_object_or_404
24from django.shortcuts import redirect
25from django.urls import reverse
26from django.views.generic import DeleteView
27from django.views.generic import FormView
28from django.views.generic import UpdateView
29from django.views.generic.detail import SingleObjectMixin
31from castellum.castellum_auth.mixins import PermissionRequiredMixin
32from castellum.castellum_auth.models import User
34from ..forms import AddMemberForm
35from ..forms import MemberForm
36from ..mixins import StudyMixin
37from ..models import Study
38from ..models import StudyMembership
41class StudyMembersView(StudyMixin, PermissionRequiredMixin, SingleObjectMixin, FormView):
42 model = Study
43 template_name = 'studies/study_members.html'
44 permission_required = 'studies.change_study'
45 tab = 'members'
47 def dispatch(self, *args, **kwargs):
48 self.object = self.get_object()
49 return super().dispatch(*args, **kwargs)
51 def get_context_data(self, **kwargs):
52 context = super().get_context_data(**kwargs)
53 context['readonly'] = self.object.status == Study.FINISHED
54 context['unprivileged_users'] = list(self.get_unprivileged_members())
55 return context
57 def get_form(self):
58 choices = [(None, '---')]
59 choices.extend([
60 (user.pk, str(user)) for user in User.objects.exclude(pk__in=self.object.members.all())
61 ])
63 form = AddMemberForm(**self.get_form_kwargs())
64 form.fields['user'].choices = choices
65 return form
67 def form_valid(self, form):
68 StudyMembership.objects.get_or_create(
69 user=form.cleaned_data['user'], study=self.object
70 )
71 return redirect('studies:members', self.object.pk)
73 def get_unprivileged_members(self):
74 max_privacy_level = self.object.get_filter_max_privacy_level()
76 for user in self.object.members.all():
77 if user.has_perm('recruitment.view_subjectfilter', obj=self.object): 77 ↛ 76line 77 didn't jump to line 76, because the condition on line 77 was never false
78 if user.get_privacy_level() < max_privacy_level: 78 ↛ 79line 78 didn't jump to line 79, because the condition on line 78 was never true
79 yield user.username
82class StudyMembershipUpdateView(StudyMixin, PermissionRequiredMixin, UpdateView):
83 model = StudyMembership
84 form_class = MemberForm
85 permission_required = 'studies.change_study'
86 study_status = [Study.EDIT, Study.EXECUTION]
87 tab = 'members'
89 def get_object(self):
90 return get_object_or_404(StudyMembership, pk=self.kwargs['pk'], study=self.study)
92 def get_success_url(self):
93 return reverse('studies:members', args=[self.object.study.pk])
96class StudyMembershipRemoveView(StudyMixin, PermissionRequiredMixin, DeleteView):
97 model = StudyMembership
98 permission_required = 'studies.change_study'
99 study_status = [Study.EDIT, Study.EXECUTION]
100 tab = 'members'
102 def get_object(self):
103 return get_object_or_404(StudyMembership, pk=self.kwargs['pk'], study=self.study)
105 def delete(self, request, *args, **kwargs):
106 membership = self.get_object()
108 if membership.user.pk == request.user.pk:
109 return HttpResponseBadRequest()
111 membership.delete()
112 return redirect('studies:members', membership.study.pk)