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

Separate serializers for members, add fields and filter backends

parent 1a694377
from django.urls import reverse from base64 import b64encode
from django.contrib.staticfiles.finders import find as find_static_file from django.contrib.staticfiles.finders import find as find_static_file
from django.urls import reverse
from rest_framework import serializers
from events.api.serializers import CalenderJSSerializer from events.api.serializers import CalenderJSSerializer
from members.models import Member from members.models import Member
from members.services import member_achievements
from rest_framework import serializers
from base64 import b64encode
class MemberBirthdaySerializer(CalenderJSSerializer): class MemberBirthdaySerializer(CalenderJSSerializer):
...@@ -46,10 +47,49 @@ class MemberBirthdaySerializer(CalenderJSSerializer): ...@@ -46,10 +47,49 @@ class MemberBirthdaySerializer(CalenderJSSerializer):
return 'white' return 'white'
class MemberSerializer(serializers.ModelSerializer): class MemberRetrieveSerializer(serializers.ModelSerializer):
class Meta:
model = Member
fields = ('pk', 'display_name', 'photo',
'birthday', 'starting_year', 'programme',
'website', 'membership_type', 'achievements')
photo = serializers.SerializerMethodField('_b64_photo')
birthday = serializers.SerializerMethodField('_birthday')
membership_type = serializers.SerializerMethodField('_membership_type')
achievements = serializers.SerializerMethodField('_achievements')
def _birthday(self, instance):
if instance.show_birthday:
return instance.birthday
return None
def _membership_type(self, instance):
membership = instance.current_membership
if membership:
return membership.type
return None
def _achievements(self, instance):
return member_achievements(instance)
def _b64_photo(self, instance):
if instance.photo:
photo = ''.join(['data:image/jpeg;base64,',
b64encode(instance.photo.file.read()).decode()])
else:
filename = find_static_file('members/images/default-avatar.jpg')
with open(filename, 'rb') as f:
photo = ''.join(['data:image/jpeg;base64,',
b64encode(f.read()).decode()])
return photo
class MemberListSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = Member model = Member
fields = ('pk', 'display_name', 'photo') fields = ('pk', 'display_name', 'photo',)
photo = serializers.SerializerMethodField('_b64_photo') photo = serializers.SerializerMethodField('_b64_photo')
......
import copy import copy
from datetime import datetime from datetime import datetime
from django.db.models import Q
from django.utils import timezone from django.utils import timezone
from rest_framework import viewsets from rest_framework import permissions
from rest_framework import viewsets, filters
from rest_framework.decorators import list_route from rest_framework.decorators import list_route
from rest_framework.exceptions import ParseError from rest_framework.exceptions import ParseError
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework import permissions
from members.api.serializers import MemberBirthdaySerializer, MemberSerializer from members.api.serializers import (MemberBirthdaySerializer,
from members.models import Member MemberRetrieveSerializer,
MemberListSerializer)
from members.models import Member, Membership
class MemberViewset(viewsets.ReadOnlyModelViewSet): class MemberViewset(viewsets.ReadOnlyModelViewSet):
queryset = Member.objects.all() queryset = Member.objects.all()
permission_classes = (permissions.IsAuthenticated,) permission_classes = (permissions.IsAuthenticated,)
serializer_class = MemberSerializer filter_backends = (filters.OrderingFilter,filters.SearchFilter,)
ordering_fields = ('starting_year', 'user__first_name', 'user__last_name')
search_fields = ('nickname', 'user__first_name',
'user__last_name', 'user__username')
def get_serializer_class(self):
if self.action == 'retrieve' or self.action == 'me':
return MemberRetrieveSerializer
return MemberListSerializer
def get_queryset(self):
if self.action == 'list':
memberships = Membership.objects.filter(
Q(until__gt=datetime.now()) | Q(until=None))
return Member.objects.filter(user__in=memberships.values('user'))
return Member.objects.all()
def _get_birthdays(self, member, start, end): def _get_birthdays(self, member, start, end):
birthdays = [] birthdays = []
...@@ -49,9 +67,9 @@ class MemberViewset(viewsets.ReadOnlyModelViewSet): ...@@ -49,9 +67,9 @@ class MemberViewset(viewsets.ReadOnlyModelViewSet):
queryset = ( queryset = (
Member Member
.active_members .active_members
.with_birthdays_in_range(start, end) .with_birthdays_in_range(start, end)
.filter(show_birthday=True) .filter(show_birthday=True)
) )
all_birthdays = [ all_birthdays = [
...@@ -65,5 +83,5 @@ class MemberViewset(viewsets.ReadOnlyModelViewSet): ...@@ -65,5 +83,5 @@ class MemberViewset(viewsets.ReadOnlyModelViewSet):
@list_route() @list_route()
def me(self, request): def me(self, request):
serializer = self.serializer_class(request.user.member) serializer = self.get_serializer_class()(request.user.member)
return Response(serializer.data) return Response(serializer.data)
from datetime import date
def member_achievements(member):
memberships = member.committeemembership_set.all()
achievements = {}
for membership in memberships:
period = {
'since': membership.since,
'until': membership.until,
'chair': membership.chair
}
if hasattr(membership.committee, 'board'):
period['role'] = membership.role
if (membership.until is None and
hasattr(membership.committee, 'board')):
period['until'] = membership.committee.board.until
name = membership.committee.name
if achievements.get(name):
achievements[name]['periods'].append(period)
if achievements[name]['earliest'] > membership.since:
achievements[name]['earliest'] = membership.since
achievements[name]['periods'].sort(key=lambda x: x['since'])
else:
achievements[name] = {
'name': name,
'periods': [period],
'earliest': membership.since,
}
mentor_years = member.mentorship_set.all()
for mentor_year in mentor_years:
name = "Mentor in {}".format(mentor_year.year)
# Ensure mentorships appear last but are sorted
earliest = date.today()
earliest = earliest.replace(year=earliest.year + mentor_year.year)
if not achievements.get(name):
achievements[name] = {
'name': name,
'earliest': earliest,
}
return sorted(achievements.values(), key=lambda x: x['earliest'])
...@@ -10,6 +10,7 @@ from django.utils.text import slugify ...@@ -10,6 +10,7 @@ from django.utils.text import slugify
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from sendfile import sendfile from sendfile import sendfile
from members.services import member_achievements
from . import models from . import models
from .forms import MemberForm from .forms import MemberForm
...@@ -98,46 +99,7 @@ def profile(request, pk=None): ...@@ -98,46 +99,7 @@ def profile(request, pk=None):
member = get_object_or_404(models.Member, user=request.user) member = get_object_or_404(models.Member, user=request.user)
# Group the memberships under the committees for easier template rendering # Group the memberships under the committees for easier template rendering
memberships = member.committeemembership_set.all() achievements = member_achievements(member)
achievements = {}
for membership in memberships:
period = {
'since': membership.since,
'until': membership.until,
'chair': membership.chair
}
if hasattr(membership.committee, 'board'):
period['role'] = membership.role
if (membership.until is None and
hasattr(membership.committee, 'board')):
period['until'] = membership.committee.board.until
name = membership.committee.name
if achievements.get(name):
achievements[name]['periods'].append(period)
if achievements[name]['earliest'] > membership.since:
achievements[name]['earliest'] = membership.since
achievements[name]['periods'].sort(key=lambda x: x['since'])
else:
achievements[name] = {
'name': name,
'periods': [period],
'earliest': membership.since,
}
mentor_years = member.mentorship_set.all()
for mentor_year in mentor_years:
name = "Mentor in {}".format(mentor_year.year)
# Ensure mentorships appear last but are sorted
earliest = date.today()
earliest = earliest.replace(year=earliest.year + mentor_year.year)
if not achievements.get(name):
achievements[name] = {
'name': name,
'earliest': earliest,
}
achievements = sorted(achievements.values(), key=lambda x: x['earliest'])
membership = member.current_membership membership = member.current_membership
membership_type = _("Former member") membership_type = _("Former member")
......
Supports Markdown
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