From 5232ac5a8aca6262cf57eb4808630c095c628cea Mon Sep 17 00:00:00 2001 From: Patrick Date: Tue, 14 Jul 2020 16:44:58 +0000 Subject: [PATCH] in the job are shown first the active members, second the inactive members. add short term and slug - as first version. delete unique filter. --- fet2020/members/admin.py | 46 ++++++++++------------ fet2020/members/forms.py | 2 +- fet2020/members/models.py | 83 +++++++++++++++++++++++++++++++++------ fet2020/members/views.py | 6 +-- 4 files changed, 97 insertions(+), 40 deletions(-) diff --git a/fet2020/members/admin.py b/fet2020/members/admin.py index 502b1c34..1f6d2424 100644 --- a/fet2020/members/admin.py +++ b/fet2020/members/admin.py @@ -1,29 +1,12 @@ from django.contrib import admin +from django.utils.translation import gettext as _ + from .models import Member, Job, JobMember from .forms import MyMemberForm, MyJobForm -from django.utils.translation import gettext as _ - -class ActiveJobFilter(admin.SimpleListFilter): - title = _('Aktiv im Job') - - parameter_name = 'is_active' - - def lookups(self, request, model_admin): - return ( - ('yes', _('Yes')), - ('no', _('No')), - ) - - def queryset(self, request, queryset): - if self.value() == 'yes': - return queryset.filter(job_end__isnull=True) - elif self.value() == 'no': - return queryset class MemberRoleFilter(admin.SimpleListFilter): title = _('Rolle') - parameter_name = 'role' def lookups(self, request, model_admin): @@ -39,19 +22,32 @@ class MemberRoleFilter(admin.SimpleListFilter): return queryset.filter(role='P') class JobMemberInline(admin.TabularInline): - list_filter = [ActiveJobFilter] model = JobMember extra = 0 - #def get_queryset(self, request): - # qs = super().get_queryset(request) - # return qs.filter(job_end__isnull=False) +class JobInline(JobMemberInline): + verbose_name = "Tätigkeit" + verbose_name_plural = "Tätigkeitsübersicht" + +class ActiveMemberInline(JobMemberInline): + verbose_name = "Mitglied" + verbose_name_plural = "Aktive Mitglieder Liste" + + def get_queryset(self, request): + return JobMember.active_member.all() + +class InactiveMemberInline(JobMemberInline): + verbose_name = "Mitglied" + verbose_name_plural = "Inaktive Mitglieder Liste" + + def get_queryset(self, request): + return JobMember.inactive_member.all() class MyMemberAdmin(admin.ModelAdmin): form = MyMemberForm model = Member list_display = ['nickname', 'firstname', 'surname', 'mailaccount', 'role'] - inlines = (JobMemberInline,) + inlines = (JobInline,) search_fields = ['firstname', 'surname','nickname','mailaccount'] list_filter = [MemberRoleFilter] @@ -66,7 +62,7 @@ class MyJobAdmin(admin.ModelAdmin): form = MyJobForm model = Job list_display = ['name'] - inlines = (JobMemberInline,) + inlines = (ActiveMemberInline, InactiveMemberInline) search_fields = ['name'] diff --git a/fet2020/members/forms.py b/fet2020/members/forms.py index 24f729f8..55dea6e9 100644 --- a/fet2020/members/forms.py +++ b/fet2020/members/forms.py @@ -25,6 +25,6 @@ class MyMemberForm(forms.ModelForm): class MyJobForm(forms.ModelForm): class Meta: model = Job - fields = ['name', 'description', 'image'] + fields = ['name', 'shortterm', 'slug', 'description', 'image'] widgets = {'description': CKEditorUploadingWidget(config_name='default')} \ No newline at end of file diff --git a/fet2020/members/models.py b/fet2020/members/models.py index f326a6f3..8be02bdf 100644 --- a/fet2020/members/models.py +++ b/fet2020/members/models.py @@ -1,10 +1,15 @@ from django.core.validators import RegexValidator from django.db import models +from django.db.models import Q +from django.utils import timezone +from django.utils.text import slugify from django.utils.translation import gettext_lazy as _ from rest_framework import serializers import uuid +from datetime import timedelta + class MemberManager(models.Manager): def get_queryset(self): @@ -14,6 +19,36 @@ class PensionManager(models.Manager): def get_queryset(self): return super().get_queryset().filter(role='P') +class ActiveMemberManager(models.Manager): + ''' + return a list of active member, and members who are still working + ''' + def get_queryset(self): + date_today = timezone.now().date() + + return super().get_queryset().filter( + Q(member__role='A') & + ( + Q(job_end__gt=date_today) | + Q(job_end__isnull=True) + ) + ) + +class InactiveMemberManager(models.Manager): + ''' + return a list of inactive member + ''' + def get_queryset(self): + date_today = timezone.now().date() + + return super().get_queryset().filter( + Q(member__role='P') | + ( + Q(job_end__lt=date_today + timedelta(days=1)) & + Q(job_end__isnull=False) + ) + ) + class Member(models.Model): firstname = models.CharField(max_length=128) surname = models.CharField(max_length=128) @@ -31,8 +66,10 @@ class Member(models.Model): birthday = models.DateField(null=True, blank=True) - phone_error_msg =_(("Phone number must be entered in the format: " - "+999999999'. Up to 15 digits allowed.")) + phone_error_msg =_(( + "Phone number must be entered in the format: " + "+999999999'. Up to 15 digits allowed." + )) phone_regex = RegexValidator(regex=r'^\+?1?\d{9,15}$', message=phone_error_msg) phone = models.CharField(validators=[phone_regex], max_length=17, blank=True) @@ -44,7 +81,7 @@ class Member(models.Model): has_jobs = models.ManyToManyField( 'Job', through='JobMember', - through_fields=('member', 'job') + through_fields=('member', 'job'), ) # Managers @@ -52,6 +89,10 @@ class Member(models.Model): active_member = MemberManager() pension_member = PensionManager() + class Meta: + verbose_name = "Mitglied" + verbose_name_plural = "Mitglieder" + def __str__(self): return self.firstname + " " + self.surname @@ -70,6 +111,9 @@ class MemberSerializer(serializers.HyperlinkedModelSerializer): class Job(models.Model): name = models.CharField(max_length=128) + shortterm = models.CharField(max_length=128) + + slug = models.SlugField(unique=True, null=True, blank=True) description = models.TextField(null=True, blank=True) image = models.ImageField(null=True, blank=True) @@ -77,15 +121,33 @@ class Job(models.Model): has_members = models.ManyToManyField( 'Member', through='JobMember', - through_fields=('job', 'member') + through_fields=('job', 'member'), ) + class Meta: + verbose_name = "Tätigkeit" + verbose_name_plural = "Tätigkeiten" + + def save(self, *args, **kwargs): + if not self.slug: + self.slug = slugify(self.shortterm) + + super().save(*args, **kwargs) + def __str__(self): - return self.name + return self.shortterm class JobMember(models.Model): - member = models.ForeignKey(Member, on_delete=models.CASCADE) - job = models.ForeignKey(Job, on_delete=models.CASCADE) + member = models.ForeignKey( + Member, + on_delete=models.CASCADE, + verbose_name = "Mitglied", + ) + job = models.ForeignKey( + Job, + on_delete=models.CASCADE, + verbose_name = "Tätigkeit", + ) job_start = models.DateField('Job Start') job_end = models.DateField('Job Ende', null=True, blank=True) @@ -100,7 +162,6 @@ class JobMember(models.Model): ] job_role = models.CharField(max_length=2, choices=__choices, default='M') - class Meta: - unique_together = [['member', 'job']] - - jobmember = models.Manager() \ No newline at end of file + jobmember = models.Manager() + active_member = ActiveMemberManager() + inactive_member = InactiveMemberManager() \ No newline at end of file diff --git a/fet2020/members/views.py b/fet2020/members/views.py index b90fac19..5bdb00b3 100644 --- a/fet2020/members/views.py +++ b/fet2020/members/views.py @@ -13,11 +13,11 @@ from django_filters.rest_framework import DjangoFilterBackend def index(request): #members = deque(Member.all_members.all()) members = deque(Member.all_members.prefetch_related('has_jobs')) - - #jobmember = deque(JobMember.jobmember.all()) + jobmembers = deque(JobMember.jobmember.all()) context = { - "member": members + "members": members, + "jobmembers" : jobmembers, } return render(request, 'members/index.html', context)