diff --git a/README.md b/README.md index 24ecc34..a0fb987 100644 --- a/README.md +++ b/README.md @@ -389,7 +389,7 @@ EMAIL_HOST=sendgrid ## DB SQL Backup & Restore process (with local.yml) * backup current db to container `docker compose -f local.yml exec postgres backup` * list backup files in container `docker compose -f local.yml exec postgres backups` -* When postgres container is up, copy all backup files from container to dev local computer `docker cp $(docker-compose -f local.yml ps -q postgres):/backups ./backups` +* When postgres container is up, copy all backup files from container to dev local computer `docker cp $(docker compose -f local.yml ps -q postgres):/backups ./backups` * When postgres container is up, copy a backup file from dev local computer to container `docker cp ./backups/ $(docker compose -f local.yml ps -q postgres):/backups/` * restore a backup from a backup file in container `docker compose -f local.yml exec postgres restore backup_2018_03_13T09_05_07.sql.gz` * print INSERT commands for a table `docker compose -f local.yml exec postgres pg_dump --column-inserts --data-only --table=<> -d attendees --username=<>` diff --git a/attendees/persons/admin.py b/attendees/persons/admin.py index f650ab8..e78cd2e 100644 --- a/attendees/persons/admin.py +++ b/attendees/persons/admin.py @@ -116,7 +116,7 @@ class FolkAdmin(PgHistoryPage, admin.ModelAdmin): "fields": ( tuple(["display_name", "display_order", "division"]), tuple(["infos"]), - tuple(["category", "id", "created", "modified"]), + tuple(["category", "id", "created", "modified", "is_removed"]), ), }, ), @@ -135,15 +135,22 @@ def get_queryset(self, request): class FolkAttendeeAdmin(PgHistoryPage, admin.ModelAdmin): readonly_fields = ["id", "created", "modified"] list_display = ("id", "folk", "attendee", "role", "infos") + search_fields = ("id", "attendee__id", "attendee__infos", "folk__id", "infos") def get_queryset(self, request): - qs = super().get_queryset(request) + message = "Not all, but only those records accessible to you will be listed here." + if request.user.is_superuser: + qs = FolkAttendee.all_objects.all() + else: + qs = super().get_queryset(request) + if request.resolver_match.func.__name__ == "changelist_view": messages.warning( request, - "Not all, but only those records accessible to you will be listed here.", + message + (" Including removed ones." if request.user.is_superuser else ""), ) - return qs.filter(division__organization=request.user.organization) + ordering = super().get_ordering(request) + return qs.filter(folk__division__organization=request.user.organization).order_by(*ordering) class RelationAdmin(PgHistoryPage, admin.ModelAdmin): diff --git a/attendees/persons/services/folk_service.py b/attendees/persons/services/folk_service.py index 5e421e4..ea57d07 100644 --- a/attendees/persons/services/folk_service.py +++ b/attendees/persons/services/folk_service.py @@ -1,7 +1,7 @@ from collections import defaultdict from datetime import datetime, timezone from django.contrib.postgres.aggregates.general import ArrayAgg -from django.db.models import Max, OuterRef, Q, Subquery +from django.db.models import Max, OuterRef, Q, Subquery, Count from attendees.occasions.models import Meet from attendees.persons.models import Attendee, Folk, Utility, AttendingMeet @@ -148,7 +148,7 @@ def families_in_participations(meet_slug, user_organization, show_paused, divisi by families for print. If an Attendee belongs to many families, only 1) lowest display order 2) the last created folkattendee will be shown. Attendees will NOT be shown if the category of the attendingmeet is "paused". For cache computation final results may contain empty families so template need to filter them out. It does - NOT provide attendee counting, as view/template does css-counter or https://stackoverflow.com/a/34059709/4257237 + NOT provide attendee counting, as view/template does css-counter """ families = {} # {family_pk: {family_name: "AAA", families: {attendee_pk: {first_name: 'XYZ', name2: 'ABC', rank: last_folkattendee_display_order, created_at: last_folkattendee_created_at}}}} attendees_cache = {} # {attendee_pk: {last_family_pk: last_family_pk, rank: last_folkattendee_display_order, created_at: last_folkattendee_created_at}} @@ -180,7 +180,9 @@ def families_in_participations(meet_slug, user_organization, show_paused, divisi householder_last_name=Subquery(attendee_subquery.values_list('last_name')[:1]), householder_first_name=Subquery(attendee_subquery.values_list('first_name')[:1]), householder_first_name2=Subquery(attendee_subquery.values_list('first_name2')[:1]), + attendee_count=Count('attendees', filter=Q(folkattendee__is_removed=False)), ).filter( + attendee_count__gt=0, category=Attendee.FAMILY_CATEGORY, is_removed=False, attendees__in=Attendee.objects.filter(