Coverage for app/venv/lib/python3.14/site-packages/weblate/wladmin/sites.py: 47%

54 statements  

« prev     ^ index     » next       coverage.py v7.15.2, created at 2026-10-07 07:15 +0000

1# Copyright © Michal Čihař <michal@weblate.org> 

2# 

3# SPDX-License-Identifier: GPL-3.0-or-later 

4 

5from __future__ import annotations 

6 

7from typing import TYPE_CHECKING 

8 

9from django.conf import settings 

10from django.contrib import admin 

11from django.contrib.admin import AdminSite, sites 

12from django.contrib.auth import REDIRECT_FIELD_NAME 

13from django.http import HttpResponseRedirect 

14from django.urls import reverse 

15from django.utils.decorators import method_decorator 

16from django.utils.translation import gettext, gettext_lazy 

17from django.views.decorators.cache import never_cache 

18 

19if TYPE_CHECKING: 19 ↛ 20line 19 didn't jump to line 20 because the condition on line 19 was never true

20 from weblate.auth.models import AuthenticatedHttpRequest 

21 

22 

23class WeblateAdminSite(AdminSite): 

24 site_header = gettext_lazy("Weblate administration") 

25 site_title = gettext_lazy("Weblate administration") 

26 index_template = "admin/weblate-index.html" 

27 enable_nav_sidebar = False 

28 

29 @property 

30 def login_form(self): # type: ignore[override] 

31 from weblate.accounts.forms import AdminLoginForm 

32 

33 return AdminLoginForm 

34 

35 def logout(self, request, extra_context=None): 

36 from weblate.accounts.views import WeblateLogoutView 

37 

38 return WeblateLogoutView.as_view()(request) 

39 

40 @method_decorator(never_cache) 

41 def login(self, request, extra_context=None): 

42 """ 

43 Display the login form for the given HttpRequest. 

44 

45 Essentially a copy of django.contrib.admin.sites.AdminSite.login 

46 """ 

47 # Since this module gets imported in the application's root package, 

48 # it cannot import models from other applications at the module level, 

49 # and django.contrib.admin.forms eventually imports User. 

50 

51 from weblate.accounts.views import BaseLoginView 

52 

53 if request.method == "GET" and self.has_permission(request): 

54 # Already logged-in, redirect to admin index 

55 index_path = reverse("admin:index", current_app=self.name) 

56 return HttpResponseRedirect(index_path) 

57 

58 context = { 

59 **self.each_context(request), 

60 "title": gettext("Sign in"), 

61 "subtitle": None, 

62 "app_path": request.get_full_path(), 

63 "username": request.user.get_username(), 

64 } 

65 if ( 

66 REDIRECT_FIELD_NAME not in request.GET 

67 and REDIRECT_FIELD_NAME not in request.POST 

68 ): 

69 context[REDIRECT_FIELD_NAME] = reverse("admin:index", current_app=self.name) 

70 context.update(extra_context or {}) 

71 

72 defaults = { 

73 "extra_context": context, 

74 "authentication_form": self.login_form, 

75 "template_name": self.login_template or "admin/login.html", 

76 } 

77 request.current_app = self.name 

78 return BaseLoginView.as_view(**defaults)(request) 

79 

80 @property 

81 def site_url(self) -> str: # type: ignore[override] 

82 if settings.URL_PREFIX: 

83 return settings.URL_PREFIX 

84 return "/" 

85 

86 def each_context(self, request: AuthenticatedHttpRequest): # type: ignore[override] 

87 from weblate.wladmin.models import ConfigurationError 

88 

89 result = super().each_context(request) 

90 empty = [gettext("Object listing turned off")] 

91 result["empty_selectable_objects_list"] = [empty] 

92 result["empty_objects_list"] = empty 

93 result["configuration_errors"] = ConfigurationError.objects.filter( 

94 ignored=False 

95 ) 

96 return result 

97 

98 

99SITE = WeblateAdminSite() 

100 

101 

102def patch_admin_site() -> None: 

103 sites.site = admin.site = SITE