Skip to content

Commit

Permalink
- forced standard MIDDLEWARE_CLASSES into tests
Browse files Browse the repository at this point in the history
- fixed columns labels into show/hide column panel
- autoregister/autodiscover
  • Loading branch information
saxix committed Apr 25, 2012
1 parent 899c80e commit e79d157
Show file tree
Hide file tree
Showing 50 changed files with 1,341 additions and 244 deletions.
15 changes: 10 additions & 5 deletions docs/source/index.rst
Original file line number Original file line Diff line number Diff line change
@@ -1,7 +1,6 @@
.. include globals.rst .. include globals.rst
.. _index: .. _index:


====================
iAdmin documentation iAdmin documentation
==================== ====================


Expand All @@ -10,9 +9,8 @@ iAdmin documentation


iAdmin is an alternative Django Admin application that offer some useful extra `features`; Can works both as replacement of standard admin application or parallel to it on an alternate url. iAdmin is an alternative Django Admin application that offer some useful extra `features`; Can works both as replacement of standard admin application or parallel to it on an alternate url.


========
Features Features
======== --------


- show/hide columns into change_list - show/hide columns into change_list
- tabbed view of inlines - tabbed view of inlines
Expand All @@ -26,16 +24,23 @@ Features
- info page for packages and application version - info page for packages and application version
- easy creation of multiple instances that use different template - easy creation of multiple instances that use different template


=================
Table Of Contents Table Of Contents
================= -----------------

.. toctree:: .. toctree::
:maxdepth: 1 :maxdepth: 1


install install
api api
screenshots screenshots


Links
~~~~~

* Project home page: https://github.com/saxix/django-iadmin
* Issue tracker: https://github.com/saxix/django-iadmin/issues?sort
* Download: http://pypi.python.org/pypi/django-iadmin/
* Docs: http://readthedocs.org/docs/django-iadmin/en/latest/


Indices and tables Indices and tables
================== ==================
Expand Down
4 changes: 2 additions & 2 deletions iadmin/actions/__init__.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
from .export import export_to_csv,export_as_json from .export import export_to_csv,export_as_json
from .mass_update import mass_update from .mass_update import mass_update
from .graph import graph_queryset from .graph import graph_queryset

from .delete import delete_selected
#__all__ = ('export_to_csv', 'mass_update') #__all__ = ('export_to_csv', 'mass_update')
77 changes: 77 additions & 0 deletions iadmin/actions/delete.py
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,77 @@
from django.core.exceptions import PermissionDenied
from django.contrib.admin import helpers
from django.contrib.admin.util import get_deleted_objects, model_ngettext
from django.db import router
from django.template.response import TemplateResponse
from django.utils.encoding import force_unicode
from django.utils.translation import ugettext_lazy, ugettext as _

def delete_selected(modeladmin, request, queryset):
"""
Default action which deletes the selected objects.
This action first displays a confirmation page whichs shows all the
deleteable objects, or, if the user has no permission one of the related
childs (foreignkeys), a "permission denied" message.
Next, it delets all selected objects and redirects back to the change list.
"""
opts = modeladmin.model._meta
app_label = opts.app_label

# Check that the user has delete permission for the actual model
if not modeladmin.has_delete_permission(request):
raise PermissionDenied

using = router.db_for_write(modeladmin.model)

# Populate deletable_objects, a data structure of all related objects that
# will also be deleted.
deletable_objects, perms_needed, protected = get_deleted_objects(
queryset, opts, request.user, modeladmin.admin_site, using)

# The user has already confirmed the deletion.
# Do the deletion and return a None to display the change list view again.
if request.POST.get('post'):
if perms_needed:
raise PermissionDenied
n = queryset.count()
if n:
for obj in queryset:
obj_display = force_unicode(obj)
modeladmin.log_deletion(request, obj, obj_display)
queryset.delete()
modeladmin.message_user(request, _("Successfully deleted %(count)d %(items)s.") % {
"count": n, "items": model_ngettext(modeladmin.opts, n)
})
# Return None to display the change list page again.
return None

if len(queryset) == 1:
objects_name = force_unicode(opts.verbose_name)
else:
objects_name = force_unicode(opts.verbose_name_plural)

if perms_needed or protected:
title = _("Cannot delete %(name)s") % {"name": objects_name}
else:
title = _("Are you sure?")

context = modeladmin.get_context_data(**{
"title": title,
"objects_name": objects_name,
"deletable_objects": [deletable_objects],
'queryset': queryset,
"perms_lacking": perms_needed,
"protected": protected,
"opts": opts,
"app_label": app_label,
'action_checkbox_name': helpers.ACTION_CHECKBOX_NAME,
})
# tpls = modeladmin.get_template(request, 'delete_selected_confirmation.html')
# Display the confirmation page
return TemplateResponse(request,
modeladmin.delete_selected_confirmation_template or modeladmin.get_template(request,'delete_selected_confirmation.html')
, context, current_app=modeladmin.admin_site.name)

delete_selected.short_description = ugettext_lazy("Delete selected %(verbose_name_plural)s")
2 changes: 1 addition & 1 deletion iadmin/actions/export.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ def export_to_csv(modeladmin, request, queryset):
adminForm = helpers.AdminForm(form, modeladmin.get_fieldsets(request), {}, [], model_admin=modeladmin) adminForm = helpers.AdminForm(form, modeladmin.get_fieldsets(request), {}, [], model_admin=modeladmin)
media = modeladmin.media + adminForm.media media = modeladmin.media + adminForm.media
tpl = modeladmin.get_template(request, 'export_csv.html' ) tpl = modeladmin.get_template(request, 'export_csv.html' )
ctx = modeladmin.get_context(**{'adminform': adminForm, ctx = modeladmin.get_context_data(**{'adminform': adminForm,
'form': form, 'form': form,
'change': True, 'change': True,
'title': _('Export to CSV'), 'title': _('Export to CSV'),
Expand Down
2 changes: 1 addition & 1 deletion iadmin/actions/mass_update.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ def mass_update(modeladmin, request, queryset):
media = modeladmin.media + adminForm.media media = modeladmin.media + adminForm.media
dthandler = lambda obj: obj.isoformat() if isinstance(obj, datetime.date) else str(obj) dthandler = lambda obj: obj.isoformat() if isinstance(obj, datetime.date) else str(obj)
tpl = modeladmin.get_template(request, 'mass_update.html' ) tpl = modeladmin.get_template(request, 'mass_update.html' )
ctx = modeladmin.get_context(**{'adminform': adminForm, ctx = modeladmin.get_context_data(**{'adminform': adminForm,
'form': form, 'form': form,
'title': u"Mass update %s" % force_unicode(modeladmin.opts.verbose_name_plural), 'title': u"Mass update %s" % force_unicode(modeladmin.opts.verbose_name_plural),
'grouped': grouped, 'grouped': grouped,
Expand Down
16 changes: 8 additions & 8 deletions iadmin/models.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -14,19 +14,19 @@ def create_extra_permission(sender, **kwargs):
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType


for model in get_models(sender): for model in get_models(sender):
for action in ('view', 'export', 'massupdate', 'import'): for action in ('read', 'export', 'massupdate', 'import'):
opts = model._meta opts = model._meta
codename = _get_permission_codename(action, opts) codename = _get_permission_codename(action, opts)
label = u'Can %s %s' % (action, opts.verbose_name_raw) label = u'Can %s %s' % (action, opts.verbose_name_raw)
ct = ContentType.objects.get_for_model(model) ct = ContentType.objects.get_for_model(model)
Permission.objects.get_or_create(codename=codename, content_type=ct, defaults={'name': label}) Permission.objects.get_or_create(codename=codename, content_type=ct, defaults={'name': label})


# restrictions # # restrictions
for model in get_models(sender): # for model in get_models(sender):
opts = model._meta # opts = model._meta
codename = u'read_only_%s' % opts.object_name.lower() # codename = u'read_only_%s' % opts.object_name.lower()
label = u'Can only read %s' % opts.verbose_name_raw # label = u'Can only read %s' % opts.verbose_name_raw
ct = ContentType.objects.get_for_model(model) # ct = ContentType.objects.get_for_model(model)
Permission.objects.get_or_create(codename=codename, content_type=ct, defaults={'name': label}) # Permission.objects.get_or_create(codename=codename, content_type=ct, defaults={'name': label})


signals.post_syncdb.connect(create_extra_permission) signals.post_syncdb.connect(create_extra_permission)
85 changes: 54 additions & 31 deletions iadmin/options.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ class Media:


def __init__(self, model, admin_site): def __init__(self, model, admin_site):
self.extra_allowed_filter = [] self.extra_allowed_filter = []
self._original_list_display = self.list_display self.full_list_display = self.list_display
DjangoModelAdmin.__init__(self, model, admin_site) DjangoModelAdmin.__init__(self, model, admin_site)
self._process_cell_filter() self._process_cell_filter()


Expand Down Expand Up @@ -94,7 +94,7 @@ def get_visible(opts):
ret = self.list_display ret = self.list_display
return ret return ret


def get_context(self, **kwargs): def get_context_data(self, **kwargs):
opts = self.model._meta opts = self.model._meta
app_label = opts.app_label app_label = opts.app_label


Expand Down Expand Up @@ -239,14 +239,13 @@ def changelist_view(self, request, extra_context=None):
selection_note_all = ungettext('%(total_count)s selected', selection_note_all = ungettext('%(total_count)s selected',
'All %(total_count)s selected', cl.result_count) 'All %(total_count)s selected', cl.result_count)


context = self.get_context(**{ context = self.get_context_data(**{
'module_name': force_unicode(opts.verbose_name_plural), 'module_name': force_unicode(opts.verbose_name_plural),
'selection_note': _('0 of %(cnt)s selected') % {'cnt': len(cl.result_list)}, 'selection_note': _('0 of %(cnt)s selected') % {'cnt': len(cl.result_list)},
'selection_note_all': selection_note_all % {'total_count': cl.result_count}, 'selection_note_all': selection_note_all % {'total_count': cl.result_count},
'title': cl.title, 'title': cl.title,
'is_popup': cl.is_popup, 'is_popup': cl.is_popup,
'cl': cl, 'cl': cl,
'original_list_display': self._original_list_display,
'media': media, 'media': media,
'has_add_permission': self.has_add_permission(request), 'has_add_permission': self.has_add_permission(request),
'app_label': app_label, 'app_label': app_label,
Expand Down Expand Up @@ -286,11 +285,11 @@ def get_template(self, request, template):
"iadmin/%s/%s/%s" % (app_label, template, opts.object_name.lower()), "iadmin/%s/%s/%s" % (app_label, template, opts.object_name.lower()),
"iadmin/%s/%s" % (app_label, template ), "iadmin/%s/%s" % (app_label, template ),
"iadmin/%s" % template, "iadmin/%s" % template,
# template template
] ]


def change_view(self, request, object_id, form_url='', extra_context=None): def change_view(self, request, object_id, form_url='', extra_context=None):
context = self.get_context(**(extra_context or {} )) context = self.get_context_data(**(extra_context or {} ))
ret = DjangoModelAdmin.change_view(self, request, object_id, form_url, context) ret = DjangoModelAdmin.change_view(self, request, object_id, form_url, context)
if request.method == 'POST' and "_saveasnew" in request.POST: if request.method == 'POST' and "_saveasnew" in request.POST:
ret = self.add_view(request, form_url=reverse('%s:%s_%s_add' % ret = self.add_view(request, form_url=reverse('%s:%s_%s_add' %
Expand Down Expand Up @@ -330,6 +329,30 @@ def lookup_allowed(self, lookup, value):
flat_filter.extend([isinstance(v, tuple) and v[0] or v for v in self.cell_filter]) flat_filter.extend([isinstance(v, tuple) and v[0] or v for v in self.cell_filter])
return clean_lookup in self.extra_allowed_filter or clean_lookup in flat_filter return clean_lookup in self.extra_allowed_filter or clean_lookup in flat_filter


def has_view_permission(self, request, obj=None):
"""
Returns True if the given request has permission to change or view
the given Django model instance.
If `obj` is None, this should return True if the given request has
permission to change *any* object of the given type.
"""
opts = self.opts
return self.has_change_permission(request, obj) or\
request.user.has_perm(opts.app_label + '.' + opts.get_view_permission())

def get_model_perms(self, request):
"""
Returns a dict of all perms for this model. This dict has the keys
``add``, ``change``, and ``delete`` mapping to the True/False for each
of those actions.
"""
return {
'add': self.has_add_permission(request),
'change': self.has_change_permission(request),
'delete': self.has_delete_permission(request),
'view': self.has_view_permission(request),
}




class IModelAdmin(IModelAdminMixin, DjangoModelAdmin): class IModelAdmin(IModelAdminMixin, DjangoModelAdmin):
Expand Down Expand Up @@ -392,18 +415,18 @@ def wrapper(*args, **kwargs):
# 'iadmin/js/jquery.url.js', # 'iadmin/js/jquery.url.js',
# ) # )


def get_model_perms(self, request): # def get_model_perms(self, request):
""" # """
Returns a dict of all perms for this model. This dict has the keys # Returns a dict of all perms for this model. This dict has the keys
``add``, ``change``, and ``delete`` mapping to the True/False for each # ``add``, ``change``, and ``delete`` mapping to the True/False for each
of those actions. # of those actions.
""" # """
return { # return {
'add': self.has_add_permission(request), # 'add': self.has_add_permission(request),
'change': self.has_change_permission(request), # 'change': self.has_change_permission(request),
'delete': self.has_delete_permission(request), # 'delete': self.has_delete_permission(request),
'view': self.has_view_permission(request), # 'view': self.has_view_permission(request),
} # }


# def get_actions(self, request): # def get_actions(self, request):
# acts = super(IModelAdmin, self).get_actions(request) # acts = super(IModelAdmin, self).get_actions(request)
Expand Down Expand Up @@ -454,17 +477,17 @@ def get_buttons(self):
# return ctx # return ctx




def has_view_permission(self, request, obj=None): # def has_view_permission(self, request, obj=None):
""" # """
Returns True if the given request has permission to change or view # Returns True if the given request has permission to change or view
the given Django model instance. # the given Django model instance.
#
If `obj` is None, this should return True if the given request has # If `obj` is None, this should return True if the given request has
permission to change *any* object of the given type. # permission to change *any* object of the given type.
""" # """
opts = self.opts # opts = self.opts
return self.has_change_permission(request, obj) or\ # return self.has_change_permission(request, obj) or\
request.user.has_perm(opts.app_label + '.' + opts.get_view_permission()) # request.user.has_perm(opts.app_label + '.' + opts.get_view_permission())


def response_add(self, request, obj, post_url_continue='../%s/'): def response_add(self, request, obj, post_url_continue='../%s/'):
opts = obj._meta opts = obj._meta
Expand Down Expand Up @@ -524,7 +547,7 @@ def response_add(self, request, obj, post_url_continue='../%s/'):
# return super(IModelAdmin, self).change_view(request, object_id, form_url, context) # return super(IModelAdmin, self).change_view(request, object_id, form_url, context)


def add_view(self, request, form_url='', extra_context=None): def add_view(self, request, form_url='', extra_context=None):
context = self.get_context(**(extra_context or {} )) context = self.get_context_data(**(extra_context or {} ))
return super(IModelAdmin, self).add_view(request, form_url, context) return super(IModelAdmin, self).add_view(request, form_url, context)




Expand Down Expand Up @@ -737,7 +760,7 @@ def display_view(self, request, object_id, extra_context=None):
inline_admin_formsets.append(inline_admin_formset) inline_admin_formsets.append(inline_admin_formset)
media = media + inline_admin_formset.media media = media + inline_admin_formset.media


context = self.get_context(**{ context = self.get_context_data(**{
'title': _('Change %s') % force_unicode(opts.verbose_name), 'title': _('Change %s') % force_unicode(opts.verbose_name),
'adminform': adminForm, 'adminform': adminForm,
'has_view_permission': self.has_view_permission(request), 'has_view_permission': self.has_view_permission(request),
Expand Down
11 changes: 4 additions & 7 deletions iadmin/proxy.py
Original file line number Original file line Diff line number Diff line change
@@ -1,10 +1,7 @@
import django.contrib.admin from iadmin.api import ITabularInline as TabularInline
import iadmin.api from iadmin.api import IModelAdmin as ModelAdmin
django.contrib.admin.site = iadmin.api.site from iadmin.api import IAdminSite as AdminSite
django.contrib.admin.ModelAdmin = iadmin.api.IModelAdmin
django.contrib.admin.TabularInline = iadmin.api.ITabularInline


from django.contrib.admin import site, ModelAdmin, TabularInline site = AdminSite( 'admin', 'admin')
from iadmin.api import * from iadmin.api import *



Loading

0 comments on commit e79d157

Please sign in to comment.