cmsmanage/reservations/admin.py

101 lines
3.0 KiB
Python
Raw Permalink Normal View History

from typing import Any
from django.contrib import admin
from django.contrib.admin.views.main import ChangeList
from django.db import models
from django.db.models import QuerySet
from django.http import HttpRequest
from django.urls import reverse
from .models import ExternalReservation, Reservation, Resource, UserReservation
@admin.register(Resource)
class ResourceAdmin(admin.ModelAdmin):
list_display = ["name", "parent", "min_length", "max_length"]
list_filter = ["parent"]
search_fields = ["name"]
show_facets = admin.ShowFacets.ALWAYS
class ReservationTypeFilter(admin.SimpleListFilter):
"""Filter by subclass"""
title = "Reservation Type"
parameter_name = "type"
# TODO: this could be automatic
_subtypes = {
"eventmeetingtime": "Event Meeting Time",
"userreservation": "User Reservation",
"externalreservation": "External Reservation",
}
def lookups(
self, request: HttpRequest, model_admin: admin.ModelAdmin
) -> list[tuple[str, str]]:
return [
("generic", "Generic Reservation"),
] + list(self._subtypes.items())
def queryset(self, request: HttpRequest, queryset: QuerySet) -> QuerySet:
if self.value() in self._subtypes:
return queryset.filter(**{f"{self.value()}__isnull": False})
elif self.value() == "generic":
return queryset.filter(
**{f"{subtype}__isnull": True for subtype in self._subtypes}
)
else:
return queryset
class SubclassChangeList(ChangeList):
def url_for_result(self, result: models.Model) -> str:
opts = type(result)._meta
return reverse(
f"admin:{opts.app_label}_{opts.model_name}_change",
args=(result.pk,),
current_app=self.model_admin.admin_site.name,
)
@admin.register(Reservation)
class ReservationAdmin(admin.ModelAdmin):
list_display = ["_title", "_resources", "start", "end"]
readonly_fields = ["google_calendar_event_id"]
list_filter = ["resources", ReservationTypeFilter]
show_facets = admin.ShowFacets.ALWAYS
date_hierarchy = "start"
def get_queryset(self, request):
return (
super()
.get_queryset(request)
.select_related("eventmeetingtime__event")
.prefetch_related("resources")
.select_subclasses()
)
@admin.display()
def _title(self, obj: Reservation):
return obj.get_title()
@admin.display()
def _resources(self, obj: Reservation):
return list(obj.resources.all()) or None
def get_changelist(self, request: HttpRequest, **kwargs: Any) -> type[ChangeList]:
return SubclassChangeList
@admin.register(UserReservation)
class UserReservationAdmin(admin.ModelAdmin):
def has_module_permission(self, request: HttpRequest) -> bool:
return False
@admin.register(ExternalReservation)
class ExternalReservationAdmin(admin.ModelAdmin):
def has_module_permission(self, request: HttpRequest) -> bool:
return False