Verified Commit b6e054d4 authored by Sébastiaan Versteeg's avatar Sébastiaan Versteeg
Browse files

Modify all usages of MemberGroup to take Society into account or use Committee if applicable

parent be6109fb
......@@ -3,17 +3,16 @@ import csv
import datetime
from django import forms
from django.db.models import Q
from django.contrib import admin, messages
from django.contrib.auth.models import Permission
from django.db.models import Q
from django.http import HttpResponse
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
from activemembers import models
from activemembers.forms import MemberGroupMembershipForm
from utils.translation import TranslatedModelAdmin
from activemembers.forms import MemberGroupMembershipForm, MemberGroupForm
from utils.snippets import datetime_to_lectureyear
from utils.translation import TranslatedModelAdmin
class MemberGroupMembershipInlineFormSet(forms.BaseInlineFormSet):
......@@ -41,27 +40,11 @@ class MemberGroupMembershipInline(admin.StackedInline):
autocomplete_fields = ('member',)
class CommitteeForm(forms.ModelForm):
"""
Solely here for performance reasons.
Needed because the `__str__()` of `Permission` (which is displayed in the
permissions selection box) also prints the corresponding app and
`content_type` for each permission.
"""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['permissions'].queryset = (Permission
.objects
.select_related('content_type'))
@admin.register(models.Committee)
class CommitteeAdmin(TranslatedModelAdmin):
"""Manage the committees"""
inlines = (MemberGroupMembershipInline,)
form = CommitteeForm
form = MemberGroupForm
list_display = ('name', 'since', 'until', 'active', 'email')
list_filter = ('until', 'active',)
search_fields = ('name', 'description')
......@@ -78,16 +61,33 @@ class CommitteeAdmin(TranslatedModelAdmin):
return instance.contact_mailinglist.name + '@thalia.nu'
return None
def get_queryset(self, request):
qs = super().get_queryset(request)
return qs.exclude(board=None)
@admin.register(models.Society)
class CommitteeAdmin(TranslatedModelAdmin):
"""Manage the societies"""
inlines = (MemberGroupMembershipInline,)
form = MemberGroupForm
list_display = ('name', 'since', 'until', 'active', 'email')
list_filter = ('until', 'active',)
search_fields = ('name', 'description')
filter_horizontal = ('permissions',)
fields = ('name', 'description', 'photo', 'permissions', 'since',
'until', 'contact_mailinglist', 'contact_email', 'active')
def email(self, instance):
if instance.contact_email:
return instance.contact_email
elif instance.contact_mailinglist:
return instance.contact_mailinglist.name + '@thalia.nu'
return None
@admin.register(models.Board)
class BoardAdmin(TranslatedModelAdmin):
"""Manage the board"""
inlines = (MemberGroupMembershipInline,)
form = CommitteeForm
form = MemberGroupForm
exclude = ('is_board',)
filter_horizontal = ('permissions',)
......@@ -95,22 +95,25 @@ class BoardAdmin(TranslatedModelAdmin):
'contact_mailinglist', 'contact_email', 'since', 'until',)
class BoardFilter(admin.SimpleListFilter):
class TypeFilter(admin.SimpleListFilter):
"""Filter memberships on board-only"""
title = _('board memberships')
parameter_name = 'board'
title = _('group memberships')
parameter_name = 'group_type'
def lookups(self, request, model_admin):
return [
('only', _('Only board memberships')),
('none', _('No board memberships')),
('boards', _('Only boards')),
('committees', _('Only committees')),
('societies', _('Only societies')),
]
def queryset(self, request, queryset):
if self.value() == 'only':
if self.value() == 'boards':
return queryset.exclude(group__board=None)
elif self.value() == 'none':
return queryset.filter(group__board=None)
elif self.value() == 'committees':
return queryset.exclude(group__committee=None)
elif self.value() == 'societies':
return queryset.exclude(group__society=None)
return queryset
......@@ -166,7 +169,7 @@ class MemberGroupMembershipAdmin(TranslatedModelAdmin):
"""Manage the group memberships"""
form = MemberGroupMembershipForm
list_display = ('member', 'group', 'since', 'until', 'chair', 'role')
list_filter = ('group', BoardFilter, LectureYearFilter,
list_filter = ('group', TypeFilter, LectureYearFilter,
ActiveMembershipsFilter)
list_select_related = ('member', 'group',)
search_fields = ('member__first_name', 'member__last_name',
......
......@@ -8,8 +8,8 @@ from django.utils import timezone
from members.models import Member
class CommitteeBackend(object):
"""Check permissions against committees"""
class MemberGroupBackend(object):
"""Check permissions against MemberGroups"""
def authenticate(self, *args, **kwargs):
"""Not implemented in this backend"""
......@@ -27,15 +27,15 @@ class CommitteeBackend(object):
except Member.DoesNotExist:
return set()
committees = member.committee_set.filter(
groups = member.membergroup_set.filter(
Q(membergroupmembership__until=None) |
Q(membergroupmembership__until__gte=timezone.now())
)
perm_cache_name = '_committee_perm_cache'
perm_cache_name = '_membergroup_perm_cache'
if not hasattr(user, perm_cache_name):
perms = (Permission.objects
.filter(committee__in=committees)
.filter(membergroup__in=groups)
.values_list('content_type__app_label', 'codename')
.order_by())
setattr(user, perm_cache_name,
......
"""The forms defined by the activemembers module"""
from django import forms
from django.contrib.auth.models import Permission
from activemembers.models import MemberGroupMembership
from members.models import Member
......@@ -14,3 +15,18 @@ class MemberGroupMembershipForm(forms.ModelForm):
class Meta:
model = MemberGroupMembership
exclude = ()
class MemberGroupForm(forms.ModelForm):
"""
Solely here for performance reasons.
Needed because the `__str__()` of `Permission` (which is displayed in the
permissions selection box) also prints the corresponding app and
`content_type` for each permission.
"""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['permissions'].queryset = (
Permission.objects.select_related('content_type'))
......@@ -17,8 +17,8 @@ from utils.translation import (ModelTranslateMeta, MultilingualField,
logger = logging.getLogger(__name__)
class ActiveMemberGroupsManager(models.Manager):
"""Returns active committees only"""
class ActiveMemberGroupManager(models.Manager):
"""Returns active objects only sorted by the localized name"""
def get_queryset(self):
return (super().get_queryset()
......@@ -27,10 +27,10 @@ class ActiveMemberGroupsManager(models.Manager):
class MemberGroup(models.Model, metaclass=ModelTranslateMeta):
"""Describes a committee"""
"""Describes a groups of members"""
objects = models.Manager()
active_objects = ActiveMemberGroupsManager()
active_objects = ActiveMemberGroupManager()
name = MultilingualField(
models.CharField,
......@@ -117,6 +117,11 @@ class MemberGroup(models.Model, metaclass=ModelTranslateMeta):
class Committee(MemberGroup):
"""Describes a committee, which is a type of MemberGroup"""
objects = models.Manager()
active_objects = ActiveMemberGroupManager()
wiki_namespace = models.CharField(
_('Wiki namespace'),
null=True,
......@@ -130,6 +135,11 @@ class Committee(MemberGroup):
class Society(MemberGroup):
"""Describes a society, which is a type of MemberGroup"""
objects = models.Manager()
active_objects = ActiveMemberGroupManager()
class Meta:
verbose_name = _('society')
verbose_name_plural = _('societies')
......@@ -137,6 +147,8 @@ class Society(MemberGroup):
class Board(MemberGroup):
"""Describes a board, which is a type of MemberGroup"""
class Meta:
verbose_name = _('board')
verbose_name_plural = _('boards')
......@@ -173,7 +185,7 @@ class Board(MemberGroup):
class ActiveMembershipManager(models.Manager):
"""
Customs manager that gets the currently active committee memberships
Custom manager that gets the currently active membergroup memberships
"""
def get_queryset(self):
......@@ -183,7 +195,7 @@ class ActiveMembershipManager(models.Manager):
class MemberGroupMembership(models.Model, metaclass=ModelTranslateMeta):
"""Describes a group membership"""
objects = models.Manager()
active_memberships = ActiveMembershipManager()
active_objects = ActiveMembershipManager()
member = models.ForeignKey(
'members.Member',
......
......@@ -2,7 +2,7 @@ from django.shortcuts import get_object_or_404, render, redirect, reverse
import datetime
from utils.snippets import datetime_to_lectureyear
from utils.translation import localize_attr_name
from .models import Board, MemberGroup, MemberGroupMembership
from .models import Board, MemberGroup, MemberGroupMembership, Committee
def committee_index(request):
......@@ -12,7 +12,7 @@ def committee_index(request):
:param request: the request object
:return: response containing the HTML
"""
committees = MemberGroup.active_objects.all().order_by(
committees = Committee.active_objects.all().order_by(
localize_attr_name('name'))
return render(request, 'activemembers/committee_index.html',
......@@ -27,11 +27,11 @@ def committee_detail(request, pk):
:param pk: pk of the selected committee
:return:
"""
committee = get_object_or_404(MemberGroup, pk=pk)
committee = get_object_or_404(Committee, pk=pk)
members = []
memberships = (MemberGroupMembership
.active_memberships
.active_objects
.filter(group=committee)
.prefetch_related('member__membergroupmembership_set'))
for membership in memberships:
......
......@@ -168,7 +168,7 @@ class EventAdmin(DoNextModelAdmin):
def _change_published(request, queryset, published):
if not request.user.is_superuser:
queryset = queryset.filter(
organiser__in=request.member.get_committees())
organiser__in=request.member.get_member_groups())
queryset.update(published=published)
def save_formset(self, request, form, formset, change):
......@@ -204,13 +204,13 @@ class EventAdmin(DoNextModelAdmin):
# Only get the current active committees the user is a member of
if not (request.user.is_superuser or
request.user.has_perm('events.override_organiser')):
kwargs['queryset'] = request.member.get_committees()
kwargs['queryset'] = request.member.get_member_groups()
else:
# Hide old boards and inactive committees for new events
if 'add' in request.path:
kwargs['queryset'] = (
MemberGroup.active_objects.all() |
MemberGroup.unfiltered_objects
MemberGroup.objects
.filter(board=None)
.exclude(until__lt=(timezone.now() -
timezone.timedelta(weeks=1)))
......
......@@ -71,7 +71,7 @@ def is_organiser(member, event):
return True
if event and member.has_perm('events.change_event'):
return member.get_committees().filter(
return member.get_member_groups().filter(
pk=event.organiser.pk).count() != 0
return False
......
# Generated by Django 2.0.8 on 2018-09-01 17:19
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('activemembers', '0034_clean_up_models'),
('mailinglists', '0012_auto_20180203_2304'),
]
operations = [
migrations.RemoveField(
model_name='mailinglist',
name='committees',
),
migrations.AddField(
model_name='mailinglist',
name='member_groups',
field=models.ManyToManyField(blank=True, help_text='Select entire groups to include in the list.', to='activemembers.MemberGroup', verbose_name='Member groups'),
),
]
......@@ -47,10 +47,10 @@ class MailingList(models.Model):
help_text=_('Select individual members to include in the list.'),
)
committees = models.ManyToManyField(
member_groups = models.ManyToManyField(
MemberGroup,
verbose_name=_("Committees"),
help_text=_('Select entire committees to include in the list.'),
verbose_name=_("Member groups"),
help_text=_('Select entire groups to include in the list.'),
blank=True,
)
......@@ -70,8 +70,8 @@ class MailingList(models.Model):
for member in self.members.all():
yield member.email
for committee in self.committees.all().prefetch_related("members"):
for member in committee.members.exclude(
for group in self.member_groups.all().prefetch_related("members"):
for member in group.members.exclude(
committeemembership__until__lt=timezone.now().date()):
yield member.email
......
......@@ -7,16 +7,18 @@ from utils.snippets import datetime_to_lectureyear
def get_automatic_lists():
memberships = (MemberGroupMembership.active_memberships
.filter(group__board=None)
.filter(chair=True)
.prefetch_related('member'))
committee_chairs = [x.member for x in memberships] + [
current_committee_chairs = (MemberGroupMembership.active_objects
.filter(group__board=None)
.filter(group__society=None)
.filter(chair=True)
.prefetch_related('member'))
committee_chair_emails = [x.member for x in current_committee_chairs] + [
Member(email='intern@thalia.nu')
]
active_committee_memberships = (MemberGroupMembership.active_memberships
active_committee_memberships = (MemberGroupMembership.active_objects
.filter(group__board=None)
.filter(group__society=None)
.prefetch_related('member'))
active_members = [x.member for x in active_committee_memberships]
......@@ -46,7 +48,7 @@ def get_automatic_lists():
active_members)
lists += _create_automatic_list(
['commissievoorzitters', 'committeechairs'], '[THALIA] [CHAIRS]',
committee_chairs, moderated=False)
committee_chair_emails, moderated=False)
lists += _create_automatic_list(
['optin'], '[THALIA] [OPTIN]', Member.current_members.filter(
profile__receive_optin=True),
......
......@@ -35,8 +35,9 @@ class ActiveMemberManager(MemberManager):
def get_queryset(self):
"""Select all committee members"""
active_memberships = (MemberGroupMembership
.active_memberships
.filter(group__board=None))
.active_objects
.filter(group__board=None)
.filter(group__society=None))
return (super().get_queryset()
.filter(membergroupmembership__in=active_memberships)
......@@ -175,9 +176,9 @@ class Member(User):
self.profile.event_permissions == 'no_drinks') and
self.current_membership is not None)
def get_committees(self):
"""Get the committees this user is a member of"""
return MemberGroup.unfiltered_objects.filter(
def get_member_groups(self):
"""Get the groups this user is a member of"""
return MemberGroup.objects.filter(
Q(membergroupmembership__member=self) &
(
Q(membergroupmembership__until=None) |
......
......@@ -177,7 +177,7 @@ PASSWORD_HASHERS = (
AUTHENTICATION_BACKENDS = [
'django.contrib.auth.backends.ModelBackend',
'activemembers.backends.CommitteeBackend',
'activemembers.backends.MemberGroupBackend',
]
REST_FRAMEWORK = {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment