rewrote the group views as class based views
This commit is contained in:
parent
9b3bec69d1
commit
bc3e7fdaab
@ -18,14 +18,7 @@ from django.utils.translation import ugettext_lazy as _, ugettext_noop
|
|||||||
from openslides.utils.forms import (
|
from openslides.utils.forms import (
|
||||||
CssClassMixin, LocalizedModelMultipleChoiceField)
|
CssClassMixin, LocalizedModelMultipleChoiceField)
|
||||||
|
|
||||||
from openslides.participant.models import OpenSlidesUser
|
from openslides.participant.models import OpenSlidesUser, OpenSlidesGroup
|
||||||
|
|
||||||
|
|
||||||
USER_APPLICATION_IMPORT_OPTIONS = [
|
|
||||||
('REASSIGN', _('Keep applications, try to reassign submitter')),
|
|
||||||
('INREVIEW', _('Keep applications, set status to "needs review"')),
|
|
||||||
('DISCARD', _('Discard applications'))
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
class UserCreateForm(forms.ModelForm, CssClassMixin):
|
class UserCreateForm(forms.ModelForm, CssClassMixin):
|
||||||
@ -50,25 +43,10 @@ class UserUpdateForm(UserCreateForm):
|
|||||||
'firstpassword')
|
'firstpassword')
|
||||||
|
|
||||||
|
|
||||||
class UsernameForm(forms.ModelForm, CssClassMixin):
|
|
||||||
class Meta:
|
|
||||||
model = User
|
|
||||||
exclude = ('first_name', 'last_name', 'email', 'is_active',
|
|
||||||
'is_superuser', 'groups', 'password', 'is_staff',
|
|
||||||
'last_login', 'date_joined', 'user_permissions')
|
|
||||||
|
|
||||||
|
|
||||||
class OpenSlidesUserForm(forms.ModelForm, CssClassMixin):
|
|
||||||
class Meta:
|
|
||||||
model = OpenSlidesUser
|
|
||||||
|
|
||||||
|
|
||||||
class GroupForm(forms.ModelForm, CssClassMixin):
|
class GroupForm(forms.ModelForm, CssClassMixin):
|
||||||
as_user = forms.BooleanField(
|
|
||||||
initial=False, required=False, label=_("Treat Group as User"),
|
|
||||||
help_text=_("The Group will appear on any place, other user does."))
|
|
||||||
permissions = LocalizedModelMultipleChoiceField(
|
permissions = LocalizedModelMultipleChoiceField(
|
||||||
queryset=Permission.objects.all(), label=_("Persmissions"))
|
queryset=Permission.objects.all(), label=_("Persmissions"),
|
||||||
|
required=False)
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(GroupForm, self).__init__(*args, **kwargs)
|
super(GroupForm, self).__init__(*args, **kwargs)
|
||||||
@ -76,9 +54,22 @@ class GroupForm(forms.ModelForm, CssClassMixin):
|
|||||||
self.fields['permissions'].initial = (
|
self.fields['permissions'].initial = (
|
||||||
[p.pk for p in kwargs['instance'].permissions.all()])
|
[p.pk for p in kwargs['instance'].permissions.all()])
|
||||||
|
|
||||||
|
def clean_name(self):
|
||||||
|
data = self.cleaned_data['name']
|
||||||
|
if self.instance.name.lower() == 'anonymous':
|
||||||
|
# Editing the anonymous-user
|
||||||
|
if self.instance.name.lower() != data.lower():
|
||||||
|
raise forms.ValidationError(
|
||||||
|
_('You can not edit the name for the anonymous user'))
|
||||||
|
else:
|
||||||
|
if data.lower() == 'anonymous':
|
||||||
|
raise forms.ValidationError(
|
||||||
|
_('Group name "%s" is reserved for internal use.') % data)
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Group
|
model = OpenSlidesGroup
|
||||||
exclude = ('permissions',)
|
|
||||||
|
|
||||||
|
|
||||||
class UsersettingsForm(forms.ModelForm, CssClassMixin):
|
class UsersettingsForm(forms.ModelForm, CssClassMixin):
|
||||||
|
@ -35,7 +35,7 @@ class OpenSlidesUser(User, PersonMixin):
|
|||||||
('guest', _('Guest')),
|
('guest', _('Guest')),
|
||||||
)
|
)
|
||||||
|
|
||||||
user = models.OneToOneField(User, unique=True, editable=False, parent_link=True)
|
user = models.OneToOneField(User, editable=False, parent_link=True)
|
||||||
category = models.CharField(
|
category = models.CharField(
|
||||||
max_length=100, null=True, blank=True, verbose_name=_("Category"),
|
max_length=100, null=True, blank=True, verbose_name=_("Category"),
|
||||||
help_text=_('Will be shown behind the name.'))
|
help_text=_('Will be shown behind the name.'))
|
||||||
@ -85,9 +85,9 @@ class OpenSlidesUser(User, PersonMixin):
|
|||||||
* delete
|
* delete
|
||||||
"""
|
"""
|
||||||
if link == 'edit':
|
if link == 'edit':
|
||||||
return ('user_edit', [str(self.user.id)])
|
return ('user_edit', [str(self.id)])
|
||||||
if link == 'delete':
|
if link == 'delete':
|
||||||
return ('user_delete', [str(self.user.id)])
|
return ('user_delete', [str(self.id)])
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
if self.name_surfix:
|
if self.name_surfix:
|
||||||
@ -103,13 +103,27 @@ class OpenSlidesUser(User, PersonMixin):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class OpenSlidesGroup(models.Model, PersonMixin):
|
class OpenSlidesGroup(Group, PersonMixin):
|
||||||
person_prefix = 'openslides_group'
|
person_prefix = 'openslides_group'
|
||||||
|
|
||||||
group = models.OneToOneField(Group)
|
group = models.OneToOneField(Group, editable=False, parent_link=True)
|
||||||
group_as_person = models.BooleanField(default=False)
|
group_as_person = models.BooleanField(default=False)
|
||||||
description = models.TextField(blank=True)
|
description = models.TextField(blank=True)
|
||||||
|
|
||||||
|
@models.permalink
|
||||||
|
def get_absolute_url(self, link='edit'):
|
||||||
|
"""
|
||||||
|
Return the URL to this user.
|
||||||
|
|
||||||
|
link can be:
|
||||||
|
* edit
|
||||||
|
* delete
|
||||||
|
"""
|
||||||
|
if link == 'edit':
|
||||||
|
return ('user_group_edit', [str(self.id)])
|
||||||
|
if link == 'delete':
|
||||||
|
return ('user_group_delete', [str(self.id)])
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return unicode(self.group)
|
return unicode(self.group)
|
||||||
|
|
||||||
@ -169,5 +183,7 @@ def user_post_save(sender, instance, signal, *args, **kwargs):
|
|||||||
|
|
||||||
@receiver(signals.post_save, sender=Group)
|
@receiver(signals.post_save, sender=Group)
|
||||||
def group_post_save(sender, instance, signal, *args, **kwargs):
|
def group_post_save(sender, instance, signal, *args, **kwargs):
|
||||||
# Creates OpenSlidesGroup
|
try:
|
||||||
openslidesgroup, new = OpenSlidesGroup.objects.get_or_create(group=instance)
|
instance.openslidesgroup
|
||||||
|
except OpenSlidesGroup.DoesNotExist:
|
||||||
|
OpenSlidesGroup(group=instance).save_base(raw=True)
|
||||||
|
@ -16,7 +16,8 @@ from django.core.urlresolvers import reverse
|
|||||||
from openslides.participant.views import (
|
from openslides.participant.views import (
|
||||||
ParticipantsListPDF, ParticipantsPasswordsPDF, Overview, UserCreateView,
|
ParticipantsListPDF, ParticipantsPasswordsPDF, Overview, UserCreateView,
|
||||||
UserUpdateView, UserDeleteView, SetUserStatusView, UserImportView,
|
UserUpdateView, UserDeleteView, SetUserStatusView, UserImportView,
|
||||||
ResetPasswordView)
|
ResetPasswordView, GroupOverviewView, GroupCreateView, GroupUpdateView,
|
||||||
|
GroupDeleteView)
|
||||||
|
|
||||||
urlpatterns = patterns('openslides.participant.views',
|
urlpatterns = patterns('openslides.participant.views',
|
||||||
url(r'^$',
|
url(r'^$',
|
||||||
@ -44,11 +45,6 @@ urlpatterns = patterns('openslides.participant.views',
|
|||||||
name='user_reset_password',
|
name='user_reset_password',
|
||||||
),
|
),
|
||||||
|
|
||||||
url(r'^print/$',
|
|
||||||
ParticipantsListPDF.as_view(),
|
|
||||||
name='user_print',
|
|
||||||
),
|
|
||||||
|
|
||||||
url(r'^(?P<pk>\d+)/status/toggle/$',
|
url(r'^(?P<pk>\d+)/status/toggle/$',
|
||||||
SetUserStatusView.as_view(),
|
SetUserStatusView.as_view(),
|
||||||
{'action': 'toggle'},
|
{'action': 'toggle'},
|
||||||
@ -73,25 +69,30 @@ urlpatterns = patterns('openslides.participant.views',
|
|||||||
),
|
),
|
||||||
|
|
||||||
url(r'^group/$',
|
url(r'^group/$',
|
||||||
'get_group_overview',
|
GroupOverviewView.as_view(),
|
||||||
name='user_group_overview',
|
name='user_group_overview',
|
||||||
),
|
),
|
||||||
|
|
||||||
url(r'^group/new/$',
|
url(r'^group/new/$',
|
||||||
'group_edit',
|
GroupCreateView.as_view(),
|
||||||
name='user_group_new',
|
name='user_group_new',
|
||||||
),
|
),
|
||||||
|
|
||||||
url(r'^group/(?P<group_id>\d+)/edit/$',
|
url(r'^group/(?P<pk>\d+)/edit/$',
|
||||||
'group_edit',
|
GroupUpdateView.as_view(),
|
||||||
name='user_group_edit',
|
name='user_group_edit',
|
||||||
),
|
),
|
||||||
|
|
||||||
url(r'^group/(?P<group_id>\d+)/del/$',
|
url(r'^group/(?P<pk>\d+)/del/$',
|
||||||
'group_delete',
|
GroupDeleteView.as_view(),
|
||||||
name='user_group_delete',
|
name='user_group_delete',
|
||||||
),
|
),
|
||||||
|
|
||||||
|
url(r'^print/$',
|
||||||
|
ParticipantsListPDF.as_view(),
|
||||||
|
name='user_print',
|
||||||
|
),
|
||||||
|
|
||||||
url(r'^passwords/print/$',
|
url(r'^passwords/print/$',
|
||||||
ParticipantsPasswordsPDF.as_view(),
|
ParticipantsPasswordsPDF.as_view(),
|
||||||
name='print_passwords',
|
name='print_passwords',
|
||||||
|
@ -52,7 +52,7 @@ from openslides.config.models import config
|
|||||||
from openslides.participant.models import OpenSlidesUser, OpenSlidesGroup
|
from openslides.participant.models import OpenSlidesUser, OpenSlidesGroup
|
||||||
from openslides.participant.api import gen_username, gen_password, import_users
|
from openslides.participant.api import gen_username, gen_password, import_users
|
||||||
from openslides.participant.forms import (
|
from openslides.participant.forms import (
|
||||||
UserCreateForm, UserUpdateForm, OpenSlidesUserForm, UsersettingsForm,
|
UserCreateForm, UserUpdateForm, UsersettingsForm,
|
||||||
UserImportForm, GroupForm, AdminPasswordChangeForm, ConfigForm)
|
UserImportForm, GroupForm, AdminPasswordChangeForm, ConfigForm)
|
||||||
|
|
||||||
|
|
||||||
@ -113,7 +113,7 @@ class Overview(ListView):
|
|||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = super(Overview, self).get_context_data(**kwargs)
|
context = super(Overview, self).get_context_data(**kwargs)
|
||||||
|
|
||||||
all_users = User.objects.count()
|
all_users = OpenSlidesUser.objects.count()
|
||||||
|
|
||||||
# quotient of selected users and all users
|
# quotient of selected users and all users
|
||||||
if all_users > 0:
|
if all_users > 0:
|
||||||
@ -347,6 +347,84 @@ class ResetPasswordView(RedirectView, SingleObjectMixin, QuestionMixin):
|
|||||||
return reverse('user_reset_password', args=[self.object.id])
|
return reverse('user_reset_password', args=[self.object.id])
|
||||||
|
|
||||||
|
|
||||||
|
class GroupOverviewView(ListView):
|
||||||
|
"""
|
||||||
|
Overview over all groups.
|
||||||
|
"""
|
||||||
|
permission_required = 'participant.can_manage_participant'
|
||||||
|
template_name = 'participant/group_overview.html'
|
||||||
|
context_object_name = 'groups'
|
||||||
|
model = OpenSlidesGroup
|
||||||
|
|
||||||
|
|
||||||
|
class GroupEditMixin(object):
|
||||||
|
"""
|
||||||
|
Methodes for the GroupCreateView and GroupUpdateView.
|
||||||
|
"""
|
||||||
|
def get_form_class(self):
|
||||||
|
delete_default_permissions()
|
||||||
|
return self.form_class
|
||||||
|
|
||||||
|
|
||||||
|
class GroupCreateView(CreateView, GroupEditMixin):
|
||||||
|
"""
|
||||||
|
Create a new group.
|
||||||
|
"""
|
||||||
|
permission_required = 'participant.can_manage_participant'
|
||||||
|
template_name = 'participant/group_edit.html'
|
||||||
|
context_object_name = 'group'
|
||||||
|
model = OpenSlidesGroup
|
||||||
|
form_class = GroupForm
|
||||||
|
success_url = 'user_group_overview'
|
||||||
|
apply_url = 'user_group_edit'
|
||||||
|
|
||||||
|
|
||||||
|
class GroupUpdateView(UpdateView, GroupEditMixin):
|
||||||
|
"""
|
||||||
|
Update an existing group.
|
||||||
|
"""
|
||||||
|
permission_required = 'participant.can_manage_participant'
|
||||||
|
template_name = 'participant/group_edit.html'
|
||||||
|
model = OpenSlidesGroup
|
||||||
|
context_object_name = 'group'
|
||||||
|
form_class = GroupForm
|
||||||
|
success_url = 'user_group_overview'
|
||||||
|
apply_url = 'user_group_edit'
|
||||||
|
|
||||||
|
|
||||||
|
class GroupDeleteView(DeleteView):
|
||||||
|
"""
|
||||||
|
Delete a Group.
|
||||||
|
"""
|
||||||
|
permission_required = 'participant.can_manage_participant'
|
||||||
|
model = OpenSlidesGroup
|
||||||
|
url = 'user_group_overview'
|
||||||
|
|
||||||
|
|
||||||
|
class Config(FormView):
|
||||||
|
"""
|
||||||
|
Config page for the participant app.
|
||||||
|
"""
|
||||||
|
permission_required = 'config.can_manage_config'
|
||||||
|
form_class = ConfigForm
|
||||||
|
template_name = 'participant/config.html'
|
||||||
|
|
||||||
|
def get_initial(self):
|
||||||
|
return {
|
||||||
|
'participant_pdf_system_url': config['participant_pdf_system_url'],
|
||||||
|
'participant_pdf_welcometext': config['participant_pdf_welcometext']
|
||||||
|
}
|
||||||
|
|
||||||
|
def form_valid(self, form):
|
||||||
|
config['participant_pdf_system_url'] = \
|
||||||
|
form.cleaned_data['participant_pdf_system_url']
|
||||||
|
config['participant_pdf_welcometext'] = \
|
||||||
|
form.cleaned_data['participant_pdf_welcometext']
|
||||||
|
messages.success(self.request,
|
||||||
|
_('Participants settings successfully saved.'))
|
||||||
|
return super(Config, self).form_valid(form)
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@template('participant/settings.html')
|
@template('participant/settings.html')
|
||||||
def user_settings(request):
|
def user_settings(request):
|
||||||
@ -391,7 +469,6 @@ def user_settings_password(request):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def login(request):
|
def login(request):
|
||||||
extra_content = {}
|
extra_content = {}
|
||||||
try:
|
try:
|
||||||
@ -411,146 +488,6 @@ def login(request):
|
|||||||
return django_login(request, template_name='participant/login.html', extra_context=extra_content)
|
return django_login(request, template_name='participant/login.html', extra_context=extra_content)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@permission_required('participant.can_manage_participant')
|
|
||||||
@template('participant/group_overview.html')
|
|
||||||
def get_group_overview(request):
|
|
||||||
"""
|
|
||||||
Show all groups.
|
|
||||||
"""
|
|
||||||
if config['system_enable_anonymous']:
|
|
||||||
groups = Group.objects.all()
|
|
||||||
else:
|
|
||||||
groups = Group.objects.exclude(name='Anonymous')
|
|
||||||
return {
|
|
||||||
'groups': groups,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@permission_required('participant.can_manage_participant')
|
|
||||||
@template('participant/group_edit.html')
|
|
||||||
def group_edit(request, group_id=None):
|
|
||||||
"""
|
|
||||||
Edit a group.
|
|
||||||
"""
|
|
||||||
if group_id is not None:
|
|
||||||
try:
|
|
||||||
group = Group.objects.get(id=group_id)
|
|
||||||
except Group.DoesNotExist:
|
|
||||||
# TODO: return a 404 Object
|
|
||||||
raise NameError("There is no group %d" % group_id)
|
|
||||||
else:
|
|
||||||
group = None
|
|
||||||
delete_default_permissions()
|
|
||||||
|
|
||||||
if request.method == 'POST':
|
|
||||||
form = GroupForm(request.POST, instance=group)
|
|
||||||
if form.is_valid():
|
|
||||||
# TODO: This can be done inside the form
|
|
||||||
group_name = form.cleaned_data['name'].lower()
|
|
||||||
|
|
||||||
# TODO: Why is this code called on any request and not only, if the
|
|
||||||
# anonymous_group is edited?
|
|
||||||
try:
|
|
||||||
anonymous_group = Group.objects.get(name='Anonymous')
|
|
||||||
except Group.DoesNotExist:
|
|
||||||
anonymous_group = None
|
|
||||||
|
|
||||||
# special handling for anonymous auth
|
|
||||||
# TODO: This code should be a form validator.
|
|
||||||
if group is None and group_name.strip().lower() == 'anonymous':
|
|
||||||
# don't allow to create this group
|
|
||||||
messages.error(request,
|
|
||||||
_('Group name "%s" is reserved for internal use.')
|
|
||||||
% group_name)
|
|
||||||
return {
|
|
||||||
'form': form,
|
|
||||||
'group': group
|
|
||||||
}
|
|
||||||
|
|
||||||
group = form.save()
|
|
||||||
try:
|
|
||||||
openslides_group = OpenSlidesGroup.objects.get(group=group)
|
|
||||||
except OpenSlidesGroup.DoesNotExist:
|
|
||||||
django_group = None
|
|
||||||
if form.cleaned_data['as_user'] and django_group is None:
|
|
||||||
OpenSlidesGroup(group=group).save()
|
|
||||||
elif not form.cleaned_data['as_user'] and django_group:
|
|
||||||
django_group.delete()
|
|
||||||
|
|
||||||
if anonymous_group is not None and \
|
|
||||||
anonymous_group.id == group.id:
|
|
||||||
# prevent name changes -
|
|
||||||
# XXX: I'm sure this could be done as *one* group.save()
|
|
||||||
group.name = 'Anonymous'
|
|
||||||
group.save()
|
|
||||||
|
|
||||||
if group_id is None:
|
|
||||||
messages.success(request,
|
|
||||||
_('New group was successfully created.'))
|
|
||||||
else:
|
|
||||||
messages.success(request, _('Group was successfully modified.'))
|
|
||||||
if not 'apply' in request.POST:
|
|
||||||
return redirect(reverse('user_group_overview'))
|
|
||||||
if group_id is None:
|
|
||||||
return redirect(reverse('user_group_edit', args=[group.id]))
|
|
||||||
else:
|
|
||||||
messages.error(request, _('Please check the form for errors.'))
|
|
||||||
else:
|
|
||||||
if group and OpenSlidesGroup.objects.filter(group=group).exists():
|
|
||||||
initial = {'as_user': True}
|
|
||||||
else:
|
|
||||||
initial = {'as_user': False}
|
|
||||||
|
|
||||||
form = GroupForm(instance=group, initial=initial)
|
|
||||||
return {
|
|
||||||
'form': form,
|
|
||||||
'group': group,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@permission_required('participant.can_manage_participant')
|
|
||||||
def group_delete(request, group_id):
|
|
||||||
"""
|
|
||||||
Delete a group.
|
|
||||||
"""
|
|
||||||
group = Group.objects.get(pk=group_id)
|
|
||||||
if request.method == 'POST':
|
|
||||||
group.delete()
|
|
||||||
messages.success(request,
|
|
||||||
_('Group <b>%s</b> was successfully deleted.') % group)
|
|
||||||
else:
|
|
||||||
gen_confirm_form(request,
|
|
||||||
_('Do you really want to delete <b>%s</b>?') % group,
|
|
||||||
reverse('user_group_delete', args=[group_id]))
|
|
||||||
return redirect(reverse('user_group_overview'))
|
|
||||||
|
|
||||||
|
|
||||||
class Config(FormView):
|
|
||||||
"""
|
|
||||||
Config page for the participant app.
|
|
||||||
"""
|
|
||||||
permission_required = 'config.can_manage_config'
|
|
||||||
form_class = ConfigForm
|
|
||||||
template_name = 'participant/config.html'
|
|
||||||
|
|
||||||
def get_initial(self):
|
|
||||||
return {
|
|
||||||
'participant_pdf_system_url': config['participant_pdf_system_url'],
|
|
||||||
'participant_pdf_welcometext': config['participant_pdf_welcometext']
|
|
||||||
}
|
|
||||||
|
|
||||||
def form_valid(self, form):
|
|
||||||
config['participant_pdf_system_url'] = \
|
|
||||||
form.cleaned_data['participant_pdf_system_url']
|
|
||||||
config['participant_pdf_welcometext'] = \
|
|
||||||
form.cleaned_data['participant_pdf_welcometext']
|
|
||||||
messages.success(self.request,
|
|
||||||
_('Participants settings successfully saved.'))
|
|
||||||
return super(Config, self).form_valid(form)
|
|
||||||
|
|
||||||
|
|
||||||
def register_tab(request):
|
def register_tab(request):
|
||||||
"""
|
"""
|
||||||
Register the participant tab.
|
Register the participant tab.
|
||||||
|
Loading…
Reference in New Issue
Block a user