PageRenderTime 42ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

/src/dingo/modeladmin.py

https://bitbucket.org/pombredanne/dingo
Python | 151 lines | 137 code | 10 blank | 4 comment | 2 complexity | 873e8a30df560e71a76669a00ed64654 MD5 | raw file
  1. import functools
  2. from django.contrib.admin.util import unquote, flatten_fieldsets, get_deleted_objects, model_ngettext, model_format_dict
  3. from django.core.urlresolvers import reverse
  4. from django.http import HttpResponse, HttpResponseRedirect
  5. from django.utils.functional import update_wrapper
  6. from django.contrib import admin
  7. from django.contrib.contenttypes.models import ContentType
  8. from django import template
  9. from django.shortcuts import render_to_response
  10. import registry
  11. def get_urls(self):
  12. """Return the URLs for the model admin, adding any model or
  13. object views.
  14. Adapted from django.contrib.admin.options.ModelAdmin.get_urls"""
  15. from django.conf.urls.defaults import patterns, url
  16. import functools
  17. def wrap_dingo_view(view):
  18. def wrapper(*args, **kwargs):
  19. return self.admin_site.admin_view(
  20. update_wrapper(functools.partial(view, self), view))(
  21. *args, **kwargs)
  22. return update_wrapper(wrapper, view)
  23. object_view_patterns = [
  24. url(r'^(.+)/%s/$' % a.__name__,
  25. wrap_dingo_view(a),
  26. name='%s_%s_%s' % (self.model._meta.app_label,
  27. self.model._meta.module_name,
  28. a.__name__))
  29. for a in registry.views(self.model, 'object')]
  30. model_view_patterns = [
  31. url(r'^%s/$' % a.__name__,
  32. wrap_dingo_view(a),
  33. name='%s_%s_%s' % (self.model._meta.app_label,
  34. self.model._meta.module_name,
  35. a.__name__))
  36. for a in registry.views(self.model, 'model')]
  37. urlpatterns = patterns('',
  38. *(model_view_patterns +
  39. object_view_patterns)) + \
  40. super(self.__class__, self).get_urls()
  41. return urlpatterns
  42. def change_view(self, request, object_id, extra_context=None):
  43. """View the change form for an object."""
  44. if extra_context is None:
  45. extra_context = {}
  46. view_links = []
  47. for view in registry.views(self.model, 'object'):
  48. url_name = 'admin:%s_%s_%s' % (self.model._meta.app_label,
  49. self.model._meta.module_name,
  50. view.__name__)
  51. view_links.append(
  52. (reverse(url_name, args=(object_id,) ),
  53. getattr(view, 'short_description', view.__name__),
  54. )
  55. )
  56. extra_context['views'] = view_links
  57. return super(self.__class__, self).change_view(
  58. request, object_id, extra_context=extra_context)
  59. def changelist_view(self, request, extra_context=None):
  60. """Custom changelist_view, including model_views in the context."""
  61. if extra_context is None:
  62. extra_context = {}
  63. view_links = []
  64. for view in registry.views(self.model, 'model'):
  65. url_name = 'admin:%s_%s_%s' % (self.model._meta.app_label,
  66. self.model._meta.module_name,
  67. view.__name__)
  68. view_links.append(
  69. (reverse(url_name),
  70. getattr(view, 'short_description', view.__name__),
  71. )
  72. )
  73. extra_context['views'] = view_links
  74. return super(self.__class__, self).changelist_view(
  75. request,
  76. extra_context=extra_context)
  77. def render_response(self, request, template_name, context, obj=None):
  78. opts = self.model._meta
  79. app_label = opts.app_label
  80. ordered_objects = opts.get_ordered_objects()
  81. context.update({
  82. 'has_add_permission': self.has_add_permission(request),
  83. 'has_change_permission': self.has_change_permission(request, obj),
  84. 'has_delete_permission': self.has_delete_permission(request, obj),
  85. 'has_file_field': True, # FIXME - this should check if form or formsets have a FileField,
  86. 'has_absolute_url': hasattr(self.model, 'get_absolute_url'),
  87. 'ordered_objects': ordered_objects,
  88. 'opts': opts,
  89. 'content_type_id': ContentType.objects.get_for_model(self.model).id,
  90. 'save_as': self.save_as,
  91. 'save_on_top': self.save_on_top,
  92. 'root_path': self.admin_site.root_path,
  93. 'app_label': opts.app_label,
  94. 'is_popup': request.REQUEST.has_key('_popup'),
  95. })
  96. context_instance = template.RequestContext(
  97. request,
  98. current_app=self.admin_site.name)
  99. return render_to_response(template_name, context,
  100. context_instance=context_instance)
  101. def instrument(admin_class):
  102. """Return an instrumented sub-class of admin_class that supports
  103. dingo's dependency injection."""
  104. subklass_dict = dict(
  105. get_urls = get_urls,
  106. changelist_view = changelist_view,
  107. change_view = change_view,
  108. render_response = render_response,
  109. )
  110. # create our new class and return it
  111. instrumented_admin = type(admin_class.__name__,
  112. (admin_class,),
  113. subklass_dict)
  114. return instrumented_admin
  115. ModelAdmin = instrument(admin.ModelAdmin)