Skip to content

Commit 4327111

Browse files
author
Viktor Bojda
committed
feat: allow overriding login view class via sbadmin config
1 parent 9b8e28a commit 4327111

File tree

2 files changed

+50
-2
lines changed

2 files changed

+50
-2
lines changed

src/django_smartbase_admin/admin/site.py

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,12 @@
44

55
from django.conf import settings
66
from django.contrib import admin
7+
from django.contrib.auth import REDIRECT_FIELD_NAME
78
from django.contrib.auth.decorators import login_not_required
8-
from django.http import HttpRequest, HttpResponse
9-
from django.urls import path, reverse_lazy, URLPattern, URLResolver
9+
from django.http import HttpRequest, HttpResponse, HttpResponseRedirect
10+
from django.urls import path, reverse_lazy, URLPattern, URLResolver, reverse
11+
from django.utils.decorators import method_decorator
12+
from django.utils.translation import gettext_lazy as _
1013
from django.views.decorators.cache import never_cache
1114
from django.views.decorators.csrf import csrf_protect
1215
from django.views.generic import TemplateView
@@ -195,5 +198,46 @@ def get_urls(self) -> list[URLPattern | URLResolver]:
195198
urls.extend(super().get_urls())
196199
return urls
197200

201+
@method_decorator(never_cache)
202+
@login_not_required
203+
def login(self, request: HttpRequest, extra_context: dict[str, Any] | None = None):
204+
"""
205+
Same as Django's built-in AdminSite.login view, except it allows the
206+
login view class to be overridden via configuration.
207+
"""
208+
if request.method == "GET" and self.has_permission(request):
209+
# Already logged-in, redirect to admin index
210+
index_path = reverse("admin:index", current_app=self.name)
211+
return HttpResponseRedirect(index_path)
212+
213+
# Since this module gets imported in the application's root package,
214+
# it cannot import models from other applications at the module level,
215+
# and django.contrib.admin.forms eventually imports User.
216+
from django.contrib.admin.forms import AdminAuthenticationForm
217+
218+
context = {
219+
**self.each_context(request),
220+
"title": _("Log in"),
221+
"subtitle": None,
222+
"app_path": request.get_full_path(),
223+
"username": request.user.get_username(),
224+
}
225+
if (
226+
REDIRECT_FIELD_NAME not in request.GET
227+
and REDIRECT_FIELD_NAME not in request.POST
228+
):
229+
context[REDIRECT_FIELD_NAME] = reverse("admin:index", current_app=self.name)
230+
context.update(extra_context or {})
231+
232+
defaults = {
233+
"extra_context": context,
234+
"authentication_form": self.login_form or AdminAuthenticationForm,
235+
"template_name": self.login_template or "admin/login.html",
236+
}
237+
request.current_app = self.name
238+
return request.request_data.configuration.login_view_class.as_view(**defaults)(
239+
request
240+
)
241+
198242

199243
sb_admin_site = SBAdminSite(name="sb_admin")

src/django_smartbase_admin/engine/configuration.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from django.contrib.auth import get_permission_codename
2+
from django.contrib.auth.views import LoginView
23
from django.db.models import Q
34

45
from django_smartbase_admin.admin.site import sb_admin_site
@@ -41,6 +42,7 @@ class SBAdminRoleConfiguration(metaclass=Singleton):
4142
global_filter_form = None
4243
filters_version = FilterVersions.FILTERS_VERSION_1
4344
default_color_scheme = ColorScheme.AUTO
45+
login_view_class = LoginView
4446

4547
def __init__(
4648
self,
@@ -50,6 +52,7 @@ def __init__(
5052
global_filter_form=None,
5153
filters_version=None,
5254
default_color_scheme=None,
55+
login_view_class=None,
5356
) -> None:
5457
super().__init__()
5558
self.default_view = default_view or self.default_view or []
@@ -60,6 +63,7 @@ def __init__(
6063
self.autocomplete_map = {}
6164
self.filters_version = filters_version or self.filters_version
6265
self.default_color_scheme = default_color_scheme or self.default_color_scheme
66+
self.login_view_class = login_view_class or self.login_view_class
6367

6468
def init_registered_views(self):
6569
registered_views = []

0 commit comments

Comments
 (0)