rewrote the group views as class based views

This commit is contained in:
Oskar Hahn 2012-08-11 10:09:54 +02:00
parent 9b3bec69d1
commit bc3e7fdaab
4 changed files with 134 additions and 189 deletions

View File

@ -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):

View File

@ -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)

View File

@ -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',

View File

@ -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.