Compare commits

..

No commits in common. "de9e0f488ae72beb90b3242ef368d9ddcf48060a" and "8732785426279c0f775a7dfa85e6689fdbdbb856" have entirely different histories.

6 changed files with 60 additions and 65 deletions

View File

@ -19,14 +19,14 @@ class GASLoginView(LoginView):
def get_context_data(self, **kwargs):
ctx = super().get_context_data(**kwargs)
css = gas_settings.MEDIA['css']
javascript = gas_settings.MEDIA['js']
js = gas_settings.MEDIA['js']
if gas_settings.EXTRA_MEDIA:
css = css + gas_settings.EXTRA_MEDIA.get('css', [])
javascript = javascript + gas_settings.EXTRA_MEDIA.get('js', [])
js = js + gas_settings.EXTRA_MEDIA.get('js', [])
ctx.update({
'logo_static_url': gas_settings.LOGO,
'css': css,
'js': javascript,
'js': js,
})
return ctx

View File

@ -7,9 +7,6 @@ urlpatterns = [
path('', views.UserList.as_view(), name="user_list"),
path('create/', views.CreateUser.as_view(), name="user_create"),
path('<int:pk>/edit/', views.UpdateUser.as_view(), name="user_update"),
path(
'<int:pk>/change-password/',
views.ChangePasswordUser.as_view(),
name="user_change_password"),
path('<int:pk>/change-password/', views.ChangePasswordUser.as_view(), name="user_change_password"),
path('<int:pk>/delete/', views.DeleteUser.as_view(), name="user_delete"),
]

View File

@ -10,7 +10,7 @@ class Entry:
self.icon = icon
self.url = url
self.roles = roles
self.children = {}
self.children = dict()
self.parent = parent
self.order = order if order is not None else float("inf")
@ -20,7 +20,7 @@ class Entry:
return super().__lt__(other)
class GASSite:
class GASSite(object):
base_role = 'admins'
def __init__(self):
@ -42,12 +42,12 @@ class GASSite:
exposed when gas is not active.
"""
if prefix in self._registry['urls']:
raise ImproperlyConfigured(f"Prefix {prefix} already in use")
raise ImproperlyConfigured("Prefix {0} already in use".format(prefix))
self._registry['urls'][prefix] = urls
def register_menu(self, name, label, url=None, icon=None, roles=None, parent=None, order=None):
if name in self._registry['menu']:
raise ImproperlyConfigured(f"Menu entry '{name}' already registered.")
raise ImproperlyConfigured("Menu entry '{0}' already registered.".format(name))
if roles is None:
roles = set()
@ -61,8 +61,8 @@ class GASSite:
if parent:
try:
parent_entry = self._registry['menu'][parent]
except KeyError as exc:
raise ImproperlyConfigured("Parent {parent} not registered.") from exc
except KeyError:
raise ImproperlyConfigured("Parent {} not registered.".format(parent))
parent_entry.children[name] = entry
self._registry['menu'][name] = entry
@ -86,7 +86,7 @@ class GASSite:
for prefix, urls in self._registry['urls'].items():
if prefix:
urlpatterns.append(
re_path(r'^{prefix}/', include(urls)),
re_path(r'^{0}/'.format(prefix), include(urls)),
)
else:
urlpatterns.append(

View File

@ -6,13 +6,13 @@ from django.utils.functional import Promise
class JSONEncoder(json.JSONEncoder):
def default(self, o):
if isinstance(o, datetime.datetime):
return o.strftime('%Y-%m-%d %H:%M')
if isinstance(o, datetime.date):
return o.strftime('%Y-%m-%d')
if isinstance(o, QuerySet):
return list(o)
if isinstance(o, Promise):
return str(o)
return json.JSONEncoder.default(self, o)
def default(self, obj):
if isinstance(obj, datetime.datetime):
return obj.strftime('%Y-%m-%d %H:%M')
if isinstance(obj, datetime.date):
return obj.strftime('%Y-%m-%d')
if isinstance(obj, QuerySet):
return list(obj)
if isinstance(obj, Promise):
return str(obj)
return json.JSONEncoder.default(self, obj)

View File

@ -1,10 +1,11 @@
import json
from django.contrib import messages
from django.contrib.admin.utils import NestedObjects
from django.core.exceptions import ImproperlyConfigured
from django.db import router
from django.http import HttpResponse, HttpResponseRedirect, HttpResponseBadRequest, JsonResponse
from django.http import HttpResponse, HttpResponseRedirect, HttpResponseBadRequest
from django.urls import reverse
from django.utils.cache import add_never_cache_headers
from django.utils.html import escape, escapejs
from django.utils.text import capfirst
from django.utils.translation import gettext_lazy as _
@ -43,26 +44,30 @@ class AjaxCommandsMixin:
"""
def post(self, request, *args, **kwargs):
if 'command' in self.request.POST:
command = self.request.POST['command']
command_processor = getattr(self, f'do_{command}', None)
command_processor = getattr(self, 'do_{0}'.format(self.request.POST['command']), None)
if command_processor is not None:
return command_processor()
return HttpResponseBadRequest()
handler = getattr(super(), 'post', self.http_method_not_allowed)
return handler(request, *args, **kwargs)
else:
return HttpResponseBadRequest()
else:
handler = getattr(super(), 'post', self.http_method_not_allowed)
return handler(request, *args, **kwargs)
def get(self, request, *args, **kwargs):
if 'command' in self.request.GET:
command = self.request.POST['command']
command_processor = getattr(self, f'send_{command}', None)
command_processor = getattr(self, 'send_{0}'.format(self.request.GET['command']), None)
if command_processor is not None:
return command_processor()
return HttpResponseBadRequest()
handler = getattr(super(), 'get', self.http_method_not_allowed)
return handler(request, *args, **kwargs)
else:
return HttpResponseBadRequest()
else:
handler = getattr(super(), 'get', self.http_method_not_allowed)
return handler(request, *args, **kwargs)
def render_json(self, data, encoder=utils.JSONEncoder):
return JsonResponse(data, json_dumps_params={"indent": 2}, encoder=encoder)
return HttpResponse(
json.dumps(data, indent=2, cls=encoder),
content_type='application/json')
class GASMixin:
@ -92,10 +97,7 @@ class GASMixin:
def dispatch(self, *args, **kwargs):
if self.check_user_forbidden():
path = self.request.path
response = HttpResponseRedirect(reverse('gas:login') + f'?next={path}')
add_never_cache_headers(response)
return response
return HttpResponseRedirect(reverse('gas:login') + '?next={}'.format(self.request.path))
return super().dispatch(*args, **kwargs)
def form_valid(self, form):
@ -117,14 +119,16 @@ class GASMixin:
# Forcing possible reverse_lazy evaluation
url = str(self.cancel_url)
return url
return self.get_success_url()
else:
return self.get_success_url()
def get_continue_url(self):
if self.continue_url:
# Forcing possible reverse_lazy evaluation
url = str(self.continue_url)
return url
raise ImproperlyConfigured("No URL to redirect to. Provide a continue_url.")
else:
raise ImproperlyConfigured("No URL to redirect to. Provide a continue_url.")
def get_header_title(self):
" Contents for the <title> tag. "
@ -148,10 +152,10 @@ class GASMixin:
def get_context_data(self, **kwargs):
ctx = super().get_context_data(**kwargs)
css = gas_settings.MEDIA['css']
javascript = gas_settings.MEDIA['js']
js = gas_settings.MEDIA['js']
if gas_settings.EXTRA_MEDIA:
css = css + gas_settings.EXTRA_MEDIA.get('css', [])
javascript = javascript + gas_settings.EXTRA_MEDIA.get('js', [])
js = js + gas_settings.EXTRA_MEDIA.get('js', [])
ctx.update({
'base_template': self.base_template,
'home_url': self.get_home_url(),
@ -163,7 +167,7 @@ class GASMixin:
'gas_title': gas_settings.TITLE,
'logo_static_url': gas_settings.LOGO,
'css': css,
'js': javascript,
'js': js,
})
return ctx
@ -182,7 +186,8 @@ class GASListView(GASMixin, ListView):
self.filter_form = self.get_filter_form()
if self.filter_form is not None and self.filter_form.is_valid():
return self.filter_form.filter(qs)
return qs
else:
return qs
def get_queryset(self):
qs = super().get_queryset()
@ -211,16 +216,13 @@ class GASCreateView(GASMixin, CreateView):
def form_valid(self, form):
response = super().form_valid(form)
if '_popup' in self.request.POST:
# escape() calls force_text.
obj_pk = escape(self.object.pk)
obj = escapejs(self.object)
return HttpResponse(
'<!DOCTYPE html><html><head><title></title></head><body>'
'<script type="text/javascript">'
f' opener.dismissAddAnotherPopup(window, "{obj_pk}", "{obj}");'
'</script></body></html>'
)
return response
'<script type="text/javascript">opener.dismissAddAnotherPopup(window, "%s", "%s");</script></body></html>' %
# escape() calls force_text.
(escape(self.object.pk), escapejs(self.object)))
else:
return response
class GASUpdateView(GASMixin, UpdateView):
@ -253,14 +255,10 @@ class GASDeleteView(GASMixin, DeleteView):
def format_callback(obj):
opts = obj._meta
name = capfirst(opts.verbose_name)
return f'{name}: {obj}'
return '%s: %s' % (capfirst(opts.verbose_name), obj)
collector.collect([self.object])
model_count = {
model._meta.verbose_name_plural: len(objs)
for model, objs in collector.model_objs.items()
}
model_count = {model._meta.verbose_name_plural: len(objs) for model, objs in collector.model_objs.items()}
return collector.nested(format_callback), model_count
def get_context_data(self, **kwargs):
@ -280,7 +278,7 @@ class GASDeleteView(GASMixin, DeleteView):
})
return ctx
def form_valid(self, form):
response = super().form_valid(form)
messages.add_message(self.request, messages.SUCCESS, self.get_deleted_text())
def delete(self, request, *args, **kwargs):
response = super().delete(request, *args, **kwargs)
messages.add_message(request, messages.SUCCESS, self.get_deleted_text())
return response

View File

@ -1 +1 @@
Django>=3.2.13,<5.0
Django==3.2.13