100 lines
3.7 KiB
Python
100 lines
3.7 KiB
Python
from __future__ import annotations
|
|
|
|
from typing import Any
|
|
|
|
from django.db.models import Model
|
|
from django.urls import URLPattern, re_path
|
|
from django.contrib import admin
|
|
from django.http import HttpRequest, HttpResponse, HttpResponseRedirect
|
|
from django.utils.encoding import force_str
|
|
from django.utils.translation import gettext as _
|
|
|
|
from config_site.single_configuration import DEFAULT_SINGLETON_INSTANCE_ID
|
|
from config_site import solo_settings
|
|
|
|
|
|
class SingletonModelAdmin(admin.ModelAdmin): # type: ignore[type-arg]
|
|
object_history_template = "admin/solo/object_history.html"
|
|
change_form_template = "admin/solo/change_form.html"
|
|
|
|
def has_add_permission(self, request: HttpRequest) -> bool:
|
|
return False
|
|
|
|
def has_delete_permission(self, request: HttpRequest, obj: Model | None = None) -> bool:
|
|
return False
|
|
|
|
def get_urls(self) -> list[URLPattern]:
|
|
urls = super().get_urls()
|
|
|
|
if not solo_settings.SOLO_ADMIN_SKIP_OBJECT_LIST_PAGE:
|
|
return urls
|
|
|
|
# _meta.model_name only exists on Django>=1.6 -
|
|
# on earlier versions, use module_name.lower()
|
|
try:
|
|
model_name = self.model._meta.model_name
|
|
except AttributeError:
|
|
model_name = self.model._meta.module_name.lower()
|
|
|
|
self.model._meta.verbose_name_plural = self.model._meta.verbose_name
|
|
url_name_prefix = '%(app_name)s_%(model_name)s' % {
|
|
'app_name': self.model._meta.app_label,
|
|
'model_name': model_name,
|
|
}
|
|
custom_urls = [
|
|
re_path(r'^history/$',
|
|
self.admin_site.admin_view(self.history_view),
|
|
{'object_id': str(self.singleton_instance_id)},
|
|
name='%s_history' % url_name_prefix),
|
|
re_path(r'^$',
|
|
self.admin_site.admin_view(self.change_view),
|
|
{'object_id': str(self.singleton_instance_id)},
|
|
name='%s_change' % url_name_prefix),
|
|
]
|
|
|
|
# By inserting the custom URLs first, we overwrite the standard URLs.
|
|
return custom_urls + urls
|
|
|
|
def response_change(self, request: HttpRequest, obj: Model) -> HttpResponseRedirect:
|
|
msg = _('%(obj)s was changed successfully.') % {
|
|
'obj': force_str(obj)}
|
|
if '_continue' in request.POST:
|
|
self.message_user(request, msg + ' ' +
|
|
_('You may edit it again below.'))
|
|
return HttpResponseRedirect(request.path)
|
|
else:
|
|
self.message_user(request, msg)
|
|
return HttpResponseRedirect("../../")
|
|
|
|
def change_view(self, request: HttpRequest, object_id: str, form_url: str = '', extra_context: dict[str, Any] | None = None) -> HttpResponse:
|
|
if object_id == str(self.singleton_instance_id):
|
|
self.model.objects.get_or_create(pk=self.singleton_instance_id)
|
|
|
|
if not extra_context:
|
|
extra_context = dict()
|
|
extra_context['skip_object_list_page'] = solo_settings.SOLO_ADMIN_SKIP_OBJECT_LIST_PAGE
|
|
|
|
return super().change_view(
|
|
request,
|
|
object_id,
|
|
form_url=form_url,
|
|
extra_context=extra_context,
|
|
)
|
|
|
|
def history_view(self, request: HttpRequest, object_id: str, extra_context: dict[str, Any] | None = None) -> HttpResponse:
|
|
if not extra_context:
|
|
extra_context = dict()
|
|
extra_context['skip_object_list_page'] = solo_settings.SOLO_ADMIN_SKIP_OBJECT_LIST_PAGE
|
|
|
|
return super().history_view(
|
|
request,
|
|
object_id,
|
|
extra_context=extra_context,
|
|
)
|
|
|
|
@property
|
|
def singleton_instance_id(self) -> int:
|
|
return getattr(self.model, 'singleton_instance_id', DEFAULT_SINGLETON_INSTANCE_ID)
|
|
|
|
|