code optimization

This commit is contained in:
2025-02-01 14:51:31 +01:00
parent ad74ae2c51
commit b1e02bbf0a
8 changed files with 92 additions and 148 deletions

View File

@@ -36,7 +36,7 @@ class JobOverviewInline(JobMemberInline):
verbose_name_plural = "Tätigkeitsübersicht" verbose_name_plural = "Tätigkeitsübersicht"
def get_queryset(self, request): def get_queryset(self, request):
return JobMember.members.get_all_jobs_sorted() return JobMember.members.get_all_jobs()
class ActiveMemberInline(JobMemberInline): class ActiveMemberInline(JobMemberInline):
@@ -81,11 +81,8 @@ class MemberAdmin(admin.ModelAdmin):
"nickname", "nickname",
"mailaccount", "mailaccount",
"role", "role",
"description",
"image", "image",
"birthday", "description",
"phone",
"address",
), ),
}, },
), ),

View File

@@ -24,8 +24,9 @@ class ActiveMemberForm(forms.ModelForm):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
member_qs = self.fields["member"].queryset.filter(role="A").order_by("firstname", "surname") self.fields["member"].queryset = (
self.fields["member"].queryset = member_qs self.fields["member"].queryset.filter(role="A").order_by("firstname", "surname")
)
class InactiveMemberForm(forms.ModelForm): class InactiveMemberForm(forms.ModelForm):
@@ -35,8 +36,9 @@ class InactiveMemberForm(forms.ModelForm):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
member_qs = self.fields["member"].queryset.order_by("firstname", "surname") self.fields["member"].queryset = self.fields["member"].queryset.order_by(
self.fields["member"].queryset = member_qs "firstname", "surname"
)
class MemberForm(forms.ModelForm): class MemberForm(forms.ModelForm):
@@ -54,9 +56,6 @@ class MemberForm(forms.ModelForm):
labels = { labels = {
"description": "Beschreibung zu der Person", "description": "Beschreibung zu der Person",
"image": "Porträt", "image": "Porträt",
"birthday": "Geburtstag",
"phone": "Telefonnummer",
"address": "Wohnadresse",
} }
widgets = {"description": CKEditorUploadingWidget(config_name="default")} widgets = {"description": CKEditorUploadingWidget(config_name="default")}

View File

@@ -17,16 +17,13 @@ class ActiveJobMemberManager(models.Manager):
def get_queryset(self): def get_queryset(self):
date_today = timezone.now().date() date_today = timezone.now().date()
qs = ( return (
super() super()
.get_queryset() .get_queryset()
.filter(Q(member__role="A") & (Q(job_end__gt=date_today) | Q(job_end__isnull=True)))
.order_by("job_role", "member__firstname", "member__surname", "job_start") .order_by("job_role", "member__firstname", "member__surname", "job_start")
) )
return qs.filter(
Q(member__role="A") & (Q(job_end__gt=date_today) | Q(job_end__isnull=True)),
)
class InactiveJobMemberManager(models.Manager): class InactiveJobMemberManager(models.Manager):
"""return a list of inactive member.""" """return a list of inactive member."""
@@ -40,39 +37,42 @@ class InactiveJobMemberManager(models.Manager):
def get_queryset(self): def get_queryset(self):
date_today = timezone.now().date() date_today = timezone.now().date()
qs = super().get_queryset().order_by("member__firstname", "member__surname", "-job_start") return (
super()
return qs.filter( .get_queryset()
Q(member__role="P") .filter(
| (Q(job_end__lt=date_today + timedelta(days=1)) & Q(job_end__isnull=False)), Q(member__role="P")
| (Q(job_end__lt=date_today + timedelta(days=1)) & Q(job_end__isnull=False))
)
.order_by("member__firstname", "member__surname", "-job_start")
) )
class JobMemberManager(models.Manager): class JobMemberManager(models.Manager):
def get_members(self, role): def get_all_jobs(self):
qs = self.get_queryset().order_by("member__firstname") return self.get_queryset().order_by(
F("job_end").desc(nulls_first=True), "-job_start", "job__name"
return qs.filter(Q(member__role=role))
def get_all_jobs_sorted(self):
qs = self.get_queryset().order_by(
F("job_end").desc(nulls_first=True),
"-job_start",
"job__name",
) )
return qs
def get_active_jobs(self, member_id): def get_active_jobs(self, member_id):
date_today = timezone.now().date() date_today = timezone.now().date()
qs = self.get_queryset().filter(member__id=member_id).order_by("-job_start", "job__name") return (
self.get_queryset()
return qs.filter(Q(job_end__gt=date_today) | Q(job_end__isnull=True)) .filter(Q(member__id=member_id) & (Q(job_end__gt=date_today) | Q(job_end__isnull=True)))
.order_by("-job_start", "job__name")
)
def get_inactive_jobs(self, member_id): def get_inactive_jobs(self, member_id):
date_today = timezone.now().date() date_today = timezone.now().date()
qs = self.get_queryset().filter(member__id=member_id).order_by("-job_start", "job__name") return (
self.get_queryset()
return qs.filter(Q(job_end__lt=date_today + timedelta(days=1)) & Q(job_end__isnull=False)) .filter(
Q(member__id=member_id)
& Q(job_end__lt=date_today + timedelta(days=1))
& Q(job_end__isnull=False)
)
.order_by("-job_start", "job__name")
)
class MemberManager(models.Manager): class MemberManager(models.Manager):

View File

@@ -26,7 +26,7 @@ class Migration(migrations.Migration):
migrations.AlterField( migrations.AlterField(
model_name='member', model_name='member',
name='phone', name='phone',
field=models.CharField(blank=True, max_length=17, validators=[members.validators.PhoneNumberValidator()]), field=models.CharField(blank=True, max_length=17),
), ),
migrations.AlterField( migrations.AlterField(
model_name='member', model_name='member',

View File

@@ -16,12 +16,12 @@ from .managers import (
MemberManager, MemberManager,
) )
from .validators import ( from .validators import (
PhoneNumberValidator,
validate_domainonly_email, validate_domainonly_email,
validate_file_size, validate_file_size,
validate_image_dimension, validate_image_dimension,
) )
fet_logo_url = settings.STATIC_URL + "img/FET-Logo-2014-quadrat.png"
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -55,23 +55,13 @@ class Member(models.Model):
default=MemberRole.ACTIVE, default=MemberRole.ACTIVE,
) )
description = models.TextField(null=True, blank=True) description = models.TextField(blank=True, default="")
image = ThumbnailerImageField( image = ThumbnailerImageField(
upload_to="uploads/members/image/", upload_to="uploads/members/image/",
validators=[validate_file_size, validate_image_dimension], validators=[validate_file_size, validate_image_dimension],
) )
birthday = models.DateField(null=True, blank=True)
phone = models.CharField(
max_length=17,
blank=True,
validators=[PhoneNumberValidator()],
)
address = models.TextField(null=True, blank=True)
date_modified = models.DateTimeField(auto_now=True) date_modified = models.DateTimeField(auto_now=True)
date_created = models.DateTimeField(auto_now_add=True) date_created = models.DateTimeField(auto_now_add=True)
@@ -88,7 +78,7 @@ class Member(models.Model):
# need to have 'View on site' link in admin app # need to have 'View on site' link in admin app
def get_absolute_url(self): def get_absolute_url(self):
return reverse("members:member", kwargs={"member_id": self.id}) return reverse("members:member", kwargs={"pk": self.pk})
def clean(self): def clean(self):
if not self.image: if not self.image:
@@ -98,7 +88,7 @@ class Member(models.Model):
try: try:
user = User.objects.get(username=self.username.lower()) user = User.objects.get(username=self.username.lower())
except User.DoesNotExist as e: except User.DoesNotExist as e:
logger.info("Username does not exist. Error: %s", e) logger.info("Username not found. Error: %s", e)
else: else:
user.first_name = self.firstname user.first_name = self.firstname
user.save() user.save()
@@ -108,35 +98,19 @@ class Member(models.Model):
@property @property
def image_url(self): def image_url(self):
if self.image: return self.image.url if self.image else fet_logo_url
return self.image.url
# return default image
return settings.STATIC_URL + "img/FET-Logo-2014-quadrat.png"
@property @property
def avatar_url(self): def avatar_url(self):
if self.image: return self.image["avatar"].url if self.image else fet_logo_url
return self.image["avatar"].url
# return default image
return settings.STATIC_URL + "img/FET-Logo-2014-quadrat.png"
@property @property
def portrait_url(self): def portrait_url(self):
if self.image: return self.image["portrait"].url if self.image else fet_logo_url
return self.image["portrait"].url
# return default image
return settings.STATIC_URL + "img/FET-Logo-2014-quadrat.png"
@property @property
def thumb_url(self): def thumb_url(self):
if self.image: return self.image["thumb"].url if self.image else fet_logo_url
return self.image["thumb"].url
# return default image
return settings.STATIC_URL + "img/FET-Logo-2014-quadrat.png"
class JobGroup(models.Model): class JobGroup(models.Model):
@@ -145,7 +119,7 @@ class JobGroup(models.Model):
shortterm = models.CharField(max_length=128, unique=True, blank=True) shortterm = models.CharField(max_length=128, unique=True, blank=True)
slug = models.SlugField(unique=True, null=True, blank=True) slug = models.SlugField(unique=True, null=True, blank=True)
description = models.TextField(null=True, blank=True) description = models.TextField(blank=True, default="")
# Managers # Managers
objects = models.Manager() objects = models.Manager()

View File

@@ -1,12 +1,13 @@
from django.urls import path from django.urls import path
from . import apps, views from . import apps
from .views import ActiveMemberListView, JobListView, MemberDetailView, MemberListView
app_name = apps.MembersConfig.name app_name = apps.MembersConfig.name
urlpatterns = [ urlpatterns = [
path("members/", views.index, name="index"), path("members/", ActiveMemberListView.as_view(), name="index"),
path("members/<str:role>/", views.members, name="members"), path("members/<str:role>/", MemberListView.as_view(), name="members"),
path("member/<int:member_id>/", views.profile, name="member"), path("member/<int:pk>/", MemberDetailView.as_view(), name="member"),
path("section/<slug:slug>/", views.jobs, name="jobs"), path("section/<slug:slug>/", JobListView.as_view(), name="jobs"),
] ]

View File

@@ -1,14 +1,4 @@
from django.core.validators import RegexValidator, ValidationError from django.core.validators import ValidationError
from django.utils.deconstruct import deconstructible
@deconstructible
class PhoneNumberValidator(RegexValidator):
regex = r"^\+?1?\d{9,15}$"
message = (
"Telefonnummer muss in diesem Format +999999999999 eingegeben werden. Bis zu 15 Zahlen "
"sind erlaubt."
)
def validate_domainonly_email(value): def validate_domainonly_email(value):

View File

@@ -1,74 +1,57 @@
import logging
from django.db.models import F from django.db.models import F
from django.http import Http404 from django.views.generic import ListView
from django.shortcuts import render from django.views.generic.detail import DetailView
from .models import JobGroup, JobMember, Member from .models import JobGroup, JobMember, Member
logger = logging.getLogger(__name__)
class ActiveMemberListView(ListView):
allow_empty = False
model = Member
template_name = "members/members.html"
def get_queryset(self):
return Member.all_members.filter(role=Member.MemberRole.ACTIVE)
def index(request): class JobListView(ListView):
members = Member.all_members.filter(role=Member.MemberRole.ACTIVE) allow_empty = False
model = JobMember
template_name = "members/jobs.html"
context = { def get_queryset(self):
"members": members, return JobMember.active_member.get_all(slug=self.kwargs["slug"]).order_by(
} F("job__order").asc(nulls_last=True), "job__name"
)
return render(request, "members/members.html", context) def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["active_job_group"] = JobGroup.objects.filter(slug=self.kwargs["slug"]).first()
return context
def jobs(request, slug=None): class MemberListView(ListView):
try: allow_empty = False
description = JobGroup.objects.filter(slug=slug).values().first()["description"] model = Member
except Exception: template_name = "members/members.html"
logger.info("Wrong job '%s'", slug)
raise Http404("wrong job")
job_members = JobMember.active_member.get_all(slug=slug).order_by( def get_queryset(self):
F("job__order").asc(nulls_last=True), if self.kwargs["role"].capitalize() in [r.label for r in Member.MemberRole]:
"job__name", return Member.all_members.filter(role=self.kwargs["role"].capitalize()[:1])
)
active_job_group = JobGroup.objects.filter(slug=slug).first()
context = { return Member.all_members.all() if self.kwargs["role"] in "all" else None
"description": description,
"job_members": job_members,
"active_job_group": active_job_group,
}
return render(request, "members/jobs.html", context)
def members(request, role=None): class MemberDetailView(DetailView):
for elem in Member.MemberRole: model = Member
if role == elem.label.lower(): template_name = "members/member.html"
members = Member.all_members.filter(role=elem.value)
break
else:
members = Member.all_members.all()
context = { def get_context_data(self, **kwargs):
"members": members, context = super().get_context_data(**kwargs)
}
return render(request, "members/members.html", context) context["active_jobs"] = JobMember.members.get_active_jobs(self.object.id)
context["inactive_jobs"] = JobMember.members.get_inactive_jobs(self.object.id)
return context
def profile(request, member_id=None):
member = Member.all_members.filter(id=member_id).first()
if not member:
logger.info("Wrong member id '%s'", member_id)
raise Http404("no member")
active_jobs = JobMember.members.get_active_jobs(member_id)
inactive_jobs = JobMember.members.get_inactive_jobs(member_id)
context = {
"member": member,
"active_jobs": active_jobs,
"inactive_jobs": inactive_jobs,
}
return render(request, "members/member.html", context)