From 5968ae69d1fb781c116023f9bcd0be72e60730e5 Mon Sep 17 00:00:00 2001 From: Samuel Zielke Date: Sun, 23 Mar 2025 14:11:12 +0100 Subject: [PATCH] Ansicht optimiert --- main/admin.py | 84 +++++++++++++++++++++++++++++++++++++++++--------- main/models.py | 58 +++++++++++++++++++++------------- 2 files changed, 107 insertions(+), 35 deletions(-) diff --git a/main/admin.py b/main/admin.py index 03485a1..309b13b 100644 --- a/main/admin.py +++ b/main/admin.py @@ -1,39 +1,95 @@ +from django import forms from django.contrib import admin import main.models as MainDB from datetime import date, datetime +from django.utils.html import format_html +from import_export import resources +from import_export.admin import ExportMixin, ImportMixin, ImportExportModelAdmin + + +class contributorsResource(resources.ModelResource): + + class Meta: + model = MainDB.contributors # Register your models here. @admin.register(MainDB.contributors) -class MainDB_contributorsAdmin(admin.ModelAdmin): +# class DeinModellAdmin(ImportExportModelAdmin): +# pass # Damit hast du Import/Export-Funktionalität im Django Admin +class MainDB_contributorsAdmin(ExportMixin, ImportMixin, admin.ModelAdmin): - list_display = ('full_name', 'da_approval', 'teamleader', 'second_teamleader', 'gender', 'birthday_year', 'get_congregation', 'pioneer', 'get_deparment', 'mobilnumber', 'email') + resource_class = contributorsResource + + list_display = ('full_name', 'actual', 'da_approval', 'leader', 'tage_anzeige', 'gender', 'birthday_year', 'get_congregation', 'pioneer', 'get_deparment', 'mobilnumber', 'email') list_filter = ('gender', 'roles', 'deparment', 'da_approval') search_fields = ('name', 'firstname', 'congregation__title', 'deparment__title', 'mobilnumber', 'email') - - def get_congregation(self, obj): - # Gebe eine durch Komma getrennte Liste der Namen der contributors zurück - return ", ".join([str(congregation) for congregation in obj.congregation.all()]) - get_congregation.short_description = 'Versammlung' # Optional: Benennung der Spalte + def get_congregation(self, obj): + return obj.congregation + get_congregation.short_description = 'Versammlung' + get_congregation.admin_order_field = 'congregation__title' + def get_deparment(self, obj): # Gebe eine durch Komma getrennte Liste der Namen der contributors zurück return ", ".join([str(deparment) for deparment in obj.deparment.all()]) get_deparment.short_description = 'Abteilung' # Optional: Benennung der Spalte - # Methode, um den vollständigen Namen zu kombinieren - def full_name(self, obj): - return f"{obj.name}, {obj.firstname}" - full_name.short_description = 'Name' # Spaltenüberschrift im Admin ändern - # Methode, um nur das Jahr des Birthdays anzuzeigen def birthday_year(self, obj): - year = obj.birthday.year if obj.birthday else None + year = obj.birthday.year if obj.birthday != None else 0 return int(datetime.strftime(date.today(), "%Y")) - year birthday_year.short_description = 'Alter' + # Teamleiter ansicht + def leader(self, obj): + if obj.teamleader: + color = "green" + elif not obj.teamleader and obj.second_teamleader: + color = "gold" + else: + color = "gray" + + status = f'' + return format_html(status) + + # Verfügbarkeit anzeigen + def tage_anzeige(self, obj): + """ Kompakte Anzeige mit 2er-Gruppen in farbigen Punkten """ + tage_pairs = [ + ("MiV", "MiN"), + ("DoV", "DoN"), + ("FrV", "FrN"), + ("SaV", "SaN"), + ("SoV", "SoN"), + ("Abbau", None) # Extra2 hat keinen Partner, wird einzeln bewertet + ] + + symbols = [] + for tag1, tag2 in tage_pairs: + active1 = obj.tage & obj.TAGE[tag1] + active2 = obj.TAGE.get(tag2, 0) and obj.tage & obj.TAGE[tag2] if tag2 else None # Sicherstellen, dass None nicht bewertet wird + + if tag2 is None: # Falls nur ein Eintrag in der Gruppe existiert + color = "green" if active1 else "red" # Entweder Grün oder Rot + else: + if active1 and active2: + color = "green" # 🟢 beide aktiv + elif active1 or active2: + color = "gold" # 🟡 nur einer aktiv + else: + color = "red" # 🔴 beide inaktiv + + symbols.append(f'') + + return format_html(" ".join(symbols)) + admin.site.register(MainDB.department) -admin.site.register(MainDB.congregation) + +@admin.register(MainDB.congregation) +class MainDB_congregationAdmin(admin.ModelAdmin): + list_display = ('id', 'title') + admin.site.register(MainDB.role) \ No newline at end of file diff --git a/main/models.py b/main/models.py index d58d962..395f47b 100644 --- a/main/models.py +++ b/main/models.py @@ -1,6 +1,6 @@ from django.db import models from phonenumber_field.modelfields import PhoneNumberField - +from django.contrib import admin # Create your models here. class department(models.Model): @@ -48,41 +48,57 @@ class role(models.Model): def get_absolute_url(self): return reverse("role_detail", kwargs={"pk": self.pk}) - class contributors(models.Model): - DAY_OPTIONS = [ - ('MI', 'Mittwoch'), - ('DO', 'Donnerstag'), - ('FRV', 'Freitag vormittag'), - ('FRN', 'Freitag nachmittag'), - ('SAV', 'Samstag vormittag'), - ('SAN', 'Samstag nachmittag'), - ('SOV', 'Sonntag vormittag'), - ('SON', 'Sonntag nachmittag'), - ('SOA', 'Sonntag abbau'), - ('MO', 'Montag'), - ] + TAGE = { + "MiV": 1, + "MiN": 2, + "DoV": 4, + "DoN": 8, + "FrV": 16, + "FrN": 32, + "SaV": 64, + "SaN": 128, + "SoV": 256, + "SoN": 512, + "Abbau": 1024, + } name = models.CharField(("name"), max_length=50) firstname = models.CharField(("vorname"), max_length=50) - birthday = models.DateField(("geburtstag"), auto_now=False, auto_now_add=False) - congregation = models.ManyToManyField("main.congregation", verbose_name=("congregation"), null=True) - roles = models.ManyToManyField("main.role", verbose_name=("role"), null=True) - pioneer = models.BooleanField(("pionier")) + birthday = models.DateField(("geburtstag"), auto_now=False, auto_now_add=False, blank=True, null=True) + congregation = models.ForeignKey("main.congregation", verbose_name=("Versammlung"), on_delete=models.SET_NULL, null=True, blank=True) + roles = models.ManyToManyField("main.role", verbose_name=("role"), null=True, blank=True) + pioneer = models.BooleanField(("pionier"), default=False) gender = models.CharField("Geschlecht",max_length=20, choices=[("M", "Männlich"), ("W", "Weiblich")]) da_approval = models.BooleanField(("Freigabe"), default=False) - deparment = models.ManyToManyField("main.department", verbose_name=("department"), null=True, blank=True) - availability = models.CharField(("Verfügbarkeit"), max_length=50, choices=DAY_OPTIONS, blank=True) + deparment = models.ManyToManyField("main.department", verbose_name=("Abteilung"), null=True, blank=True) + tage = models.IntegerField(default=0) # Hier speichern wir die Bitmaske teamleader = models.BooleanField(("Leiter"), default=False) - second_teamleader = models.BooleanField(("V-Leiter"), default=False) + second_teamleader = models.BooleanField(("Gruppenleiter"), default=False) mobilnumber = PhoneNumberField(("Mobilnummer"), null=True, blank=True) email = models.EmailField(("E-Mail"), max_length=254, null=True, blank=True) + jwpub = models.EmailField(("JWPUB"), max_length=254, null=True, blank=True) + notes = models.CharField(("Bemerkung"), max_length=255, null=True, blank=True) + actual = models.BooleanField(("Aktuell"), default=False) class Meta: verbose_name = ("Helfer") verbose_name_plural = ("Helfer") + @property + @admin.display( + ordering="name", + description="Name, Vorname", + boolean=False, + ) + def full_name(self): + return self.name + ", " + self.firstname + + def get_tage_list(self): + """ Gibt eine Liste der aktiven Tage zurück """ + return [name for name, bit in self.TAGE.items() if self.tage & bit] + def __str__(self): return f'{self.name}, {self.firstname}'