mirror of
https://github.com/jazzband/django-admin2.git
synced 2026-03-16 22:20:24 +00:00
185 lines
6.8 KiB
Python
185 lines
6.8 KiB
Python
import os
|
|
|
|
from django.contrib.auth.views import redirect_to_login
|
|
from django.core.exceptions import PermissionDenied
|
|
from django.forms.models import modelform_factory
|
|
from django.http import HttpResponseRedirect
|
|
from django.urls import reverse, reverse_lazy
|
|
from django.utils.encoding import force_str
|
|
from django.utils.text import get_text_list
|
|
from django.utils.translation import ugettext as _
|
|
|
|
# braces 1.3 views exported AccessMixin
|
|
# in braces 1.4 this was moved views._access and not exported in views
|
|
# not sure if this was the intent of braces or an oversight
|
|
# if intent - should look at AccessMixin vs. using a more specific mixin
|
|
try:
|
|
from braces.views import AccessMixin
|
|
except ImportError:
|
|
from braces.views._access import AccessMixin
|
|
|
|
from . import settings, permissions
|
|
from .utils import admin2_urlname, model_options
|
|
|
|
|
|
class PermissionMixin(AccessMixin):
|
|
do_not_call_in_templates = True
|
|
permission_classes = (permissions.IsStaffPermission,)
|
|
login_url = reverse_lazy('admin2:dashboard')
|
|
|
|
def __init__(self, **kwargs):
|
|
self.permissions = [
|
|
permission_class()
|
|
for permission_class in self.permission_classes]
|
|
super(PermissionMixin, self).__init__(**kwargs)
|
|
|
|
def has_permission(self, obj=None):
|
|
'''
|
|
Return ``True`` if the permission for this view shall be granted,
|
|
``False`` otherwise. Supports object-level permission by passing the
|
|
related object as first argument.
|
|
'''
|
|
for permission in self.permissions:
|
|
if not permission.has_permission(self.request, self, obj):
|
|
return False
|
|
return True
|
|
|
|
def dispatch(self, request, *args, **kwargs):
|
|
# Raise exception or redirect to login if user doesn't have
|
|
# permissions.
|
|
if not self.has_permission():
|
|
if self.raise_exception:
|
|
raise PermissionDenied # return a forbidden response
|
|
else:
|
|
return redirect_to_login(
|
|
request.get_full_path(),
|
|
self.get_login_url(),
|
|
self.get_redirect_field_name())
|
|
return super(PermissionMixin, self).dispatch(request, *args, **kwargs)
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = super(PermissionMixin, self).get_context_data(**kwargs)
|
|
permission_checker = permissions.TemplatePermissionChecker(
|
|
self.request, self.model_admin)
|
|
context.update({
|
|
'permissions': permission_checker,
|
|
})
|
|
return context
|
|
|
|
|
|
class Admin2Mixin(PermissionMixin):
|
|
# are set in the ModelAdmin2 class when creating the view via
|
|
# .as_view(...)
|
|
model_admin = None
|
|
model_name = None
|
|
app_label = None
|
|
login_view = None
|
|
|
|
index_path = reverse_lazy('admin2:dashboard')
|
|
|
|
def get_template_names(self):
|
|
return [os.path.join(
|
|
settings.ADMIN2_THEME_DIRECTORY, self.default_template_name)]
|
|
|
|
def get_templates(self):
|
|
return os.path.join(settings.ADMIN2_THEME_DIRECTORY, self.default_template_name)
|
|
|
|
def get_model(self):
|
|
return self.model
|
|
|
|
def get_queryset(self):
|
|
return self.get_model()._default_manager.all()
|
|
|
|
def get_form_class(self):
|
|
if self.form_class is not None:
|
|
return self.form_class
|
|
return modelform_factory(self.get_model())
|
|
|
|
def is_user(self, request):
|
|
return hasattr(request, 'user') and not (request.user.is_active and
|
|
request.user.is_staff)
|
|
|
|
def dispatch(self, request, *args, **kwargs):
|
|
|
|
if self.is_user(request):
|
|
if request.path == reverse('admin2:logout'):
|
|
return HttpResponseRedirect(self.index_path)
|
|
|
|
if request.path == self.index_path:
|
|
extra = {
|
|
'next': request.GET.get('next', self.index_path)
|
|
}
|
|
return self.login_view().dispatch(request, extra_context=extra, *args, **kwargs)
|
|
|
|
return super(Admin2Mixin, self).dispatch(request, *args, **kwargs)
|
|
|
|
|
|
class Admin2ModelMixin(Admin2Mixin):
|
|
model_admin = None
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = super(Admin2ModelMixin, self).get_context_data(**kwargs)
|
|
model = self.get_model()
|
|
model_meta = model_options(model)
|
|
app_verbose_names = self.model_admin.admin.app_verbose_names
|
|
context.update({
|
|
'app_label': model_meta.app_label,
|
|
'app_verbose_name': app_verbose_names.get(model_meta.app_label),
|
|
'model_name': model_meta.verbose_name,
|
|
'model_name_pluralized': model_meta.verbose_name_plural
|
|
})
|
|
return context
|
|
|
|
def get_model(self):
|
|
return self.model
|
|
|
|
def get_queryset(self):
|
|
return self.get_model()._default_manager.all()
|
|
|
|
def get_form_class(self):
|
|
if self.form_class is not None:
|
|
return self.form_class
|
|
return modelform_factory(self.get_model(), fields='__all__')
|
|
|
|
|
|
class Admin2ModelFormMixin(object):
|
|
def get_success_url(self):
|
|
if '_continue' in self.request.POST:
|
|
view_name = admin2_urlname(self, 'update')
|
|
return reverse(view_name, kwargs={'pk': self.object.pk})
|
|
|
|
if '_addanother' in self.request.POST:
|
|
return reverse(admin2_urlname(self, 'create'))
|
|
|
|
# default to index view
|
|
return reverse(admin2_urlname(self, 'index'))
|
|
|
|
def construct_change_message(self, request, form, formsets):
|
|
""" Construct a change message from a changed object """
|
|
change_message = []
|
|
if form.changed_data:
|
|
change_message.append(
|
|
_('Changed {0}.'.format(
|
|
get_text_list(form.changed_data, _('and')))))
|
|
|
|
if formsets:
|
|
for formset in formsets:
|
|
for added_object in formset.new_objects:
|
|
change_message.append(
|
|
_('Added {0} "{1}".'.format(
|
|
force_str(added_object._meta.verbose_name),
|
|
force_str(added_object))))
|
|
for changed_object, changed_fields in formset.changed_objects:
|
|
change_message.append(
|
|
_('Changed {0} for {1} "{2}".'.format(
|
|
get_text_list(changed_fields, _('and')),
|
|
force_str(changed_object._meta.verbose_name),
|
|
force_str(changed_object))))
|
|
for deleted_object in formset.deleted_objects:
|
|
change_message.append(
|
|
_('Deleted {0} "{1}".'.format(
|
|
force_str(deleted_object._meta.verbose_name),
|
|
force_str(deleted_object))))
|
|
|
|
change_message = ' '.join(change_message)
|
|
return change_message or _('No fields changed.')
|