Ticket #2383: deletelist.patch

File deletelist.patch, 9.4 KB (added by atlithorn, 18 years ago)

updated patch, based on jay's patch

  • contrib/admin/media/css/global.css

     
    135135.object-tools a.viewsitelink:hover, .object-tools a.golink:hover { background:#5b80b2 url(../img/admin/tooltag-arrowright_over.gif) top right no-repeat; }
    136136.object-tools a.addlink { background:#999 url(../img/admin/tooltag-add.gif) top right no-repeat; padding-right:28px; }
    137137.object-tools a.addlink:hover { background:#5b80b2 url(../img/admin/tooltag-add_over.gif) top right no-repeat; }
     138.object-tools a.deletelink { background:#999 url(../img/admin/tooltag-delete.gif) top right no-repeat; padding-right:28px; }
     139.object-tools a.deletelink:hover { background:#5b80b2 url(../img/admin/tooltag-delete_over.gif) top right no-repeat; }
    138140
    139141/* OBJECT HISTORY */
    140142table#change-history { width:100%; }
  • contrib/admin/templates/admin/change_list.html

     
    77{% block coltype %}flex{% endblock %}
    88{% block content %}
    99<div id="content-main">
    10 {% if has_add_permission %}
    11 <ul class="object-tools"><li><a href="add/{% if is_popup %}?_popup=1{% endif %}" class="addlink">{% blocktrans with cl.opts.verbose_name|escape as name %}Add {{ name }}{% endblocktrans %}</a></li></ul>
    12 {% endif %}
     10<ul class="object-tools">
     11        {% if has_add_permission %}
     12                <li>
     13                        <a href="add/{% if is_popup %}?_popup=1{% endif %}" class="addlink">{% blocktrans with cl.opts.verbose_name|escape as name %}Add {{ name }}{% endblocktrans %}</a>
     14                </li>
     15        {% endif %}
     16        {% if has_delete_permission %}
     17                <li>
     18                        <a href="#" onclick="document.getElementById('delete_checked_form').submit();" class="deletelink">{% blocktrans with cl.opts.verbose_name|escape as name %}Delete checked {{ name }}{% endblocktrans %}</a>
     19                </li>
     20        {% endif %}
     21</ul>
    1322<div class="module{% if cl.has_filters %} filtered{% endif %}" id="changelist">
    1423{% block search %}{% search_form cl %}{% endblock %}
    1524{% block date_hierarchy %}{% date_hierarchy cl %}{% endblock %}
    1625{% block filters %}{% filters cl %}{% endblock %}
    17 {% block result_list %}{% result_list cl %}{% endblock %}
     26{% block result_list %}{% result_list cl user %}{% endblock %}
    1827{% block pagination %}{% pagination cl %}{% endblock %}
    1928</div>
    2029</div>
  • contrib/admin/templates/admin/change_list_results.html

     
    11{% if results %}
     2<form name="delete_checked_form" id="delete_checked_form"method="POST" action="delete/">
    23<table cellspacing="0">
    34<thead>
    45<tr>
     
    1415{% endfor %}
    1516</tbody>
    1617</table>
     18</form>
    1719{% endif %}
  • contrib/admin/templatetags/admin_list.py

     
    6666    }
    6767pagination = register.inclusion_tag('admin/pagination.html')(pagination)
    6868
    69 def result_headers(cl):
     69def result_headers(cl, user):
    7070    lookup_opts = cl.lookup_opts
    7171
    7272    for i, field_name in enumerate(lookup_opts.admin.list_display):
     
    100100                       "sortable": True,
    101101                       "url": cl.get_query_string({ORDER_VAR: i, ORDER_TYPE_VAR: new_order_type}),
    102102                       "class_attrib": (th_classes and ' class="%s"' % ' '.join(th_classes) or '')}
     103    delete_permission = '%s.%s' % (cl.model._meta.app_label, cl.opts.get_delete_permission())
     104    if user.get_all_permissions().__contains__(delete_permission):
     105        yield{"text":"Delete?"}
    103106
    104 def items_for_result(cl, result):
     107def items_for_result(cl, result, user):
    105108    first = True
    106109    pk = cl.lookup_opts.pk.attname
    107110    for field_name in cl.lookup_opts.admin.list_display:
     
    173176                (table_tag, row_class, url, (cl.is_popup and ' onclick="opener.dismissRelatedLookupPopup(window, %r); return false;"' % result_id or ''), result_repr, table_tag))
    174177        else:
    175178            yield ('<td%s>%s</td>' % (row_class, result_repr))
     179    delete_permision = '%s.%s' % (cl.model._meta.app_label, cl.opts.get_delete_permission())
     180    if user.get_all_permissions().__contains__(delete_permision) or user.is_superuser:
     181        yield('<td><input type="checkbox" name="%s" /></td>' % result_id)
    176182
    177 def results(cl):
     183def results(cl, user):
    178184    for res in cl.result_list:
    179         yield list(items_for_result(cl,res))
     185        yield list(items_for_result(cl,res, user))
    180186
    181 def result_list(cl):
     187def result_list(cl, user):
    182188    return {'cl': cl,
    183             'result_headers': list(result_headers(cl)),
    184             'results': list(results(cl))}
     189            'result_headers': list(result_headers(cl, user)),
     190            'results': list(results(cl, user))}
    185191result_list = register.inclusion_tag("admin/change_list_results.html")(result_list)
    186192
    187193def date_hierarchy(cl):
  • contrib/admin/urls.py

     
    3333    # Add/change/delete/history
    3434    ('^([^/]+)/([^/]+)/$', 'django.contrib.admin.views.main.change_list'),
    3535    ('^([^/]+)/([^/]+)/add/$', 'django.contrib.admin.views.main.add_stage'),
     36    ('^([^/]+)/([^/]+)/delete/$', 'django.contrib.admin.views.main.delete_checked'),
    3637    ('^([^/]+)/([^/]+)/(.+)/history/$', 'django.contrib.admin.views.main.history'),
    3738    ('^([^/]+)/([^/]+)/(.+)/delete/$', 'django.contrib.admin.views.main.delete_stage'),
    3839    ('^([^/]+)/([^/]+)/(.+)/$', 'django.contrib.admin.views.main.change_stage'),
  • contrib/admin/views/main.py

     
    738738
    739739def change_list(request, app_label, model_name):
    740740    model = models.get_model(app_label, model_name)
     741    opts = model._meta
     742    auto_populated_fields = [f for f in opts.fields if f.prepopulate_from]
     743    field_sets = opts.admin.get_field_sets(opts)
    741744    if model is None:
    742745        raise Http404, "App %r, model %r, not found" % (app_label, model_name)
    743746    if not request.user.has_perm(app_label + '.' + model._meta.get_change_permission()):
     
    759762        'cl': cl,
    760763    })
    761764    c.update({'has_add_permission': c['perms'][app_label][cl.opts.get_add_permission()]}),
     765    c.update({'has_delete_permission': c['perms'][app_label][cl.opts.get_delete_permission()]}),
     766    c.update({'javascript_imports': get_javascript_imports(opts, auto_populated_fields, field_sets)}),
    762767    return render_to_response(['admin/%s/%s/change_list.html' % (app_label, cl.opts.object_name.lower()),
    763768                               'admin/%s/change_list.html' % app_label,
    764769                               'admin/change_list.html'], context_instance=c)
    765770change_list = staff_member_required(never_cache(change_list))
     771
     772def delete_checked (request,app_label, model_name):
     773    "Essentially the same as delete stage only for a list of objects in post parameters"
     774    import sets
     775    model = models.get_model(app_label, model_name)
     776    if model is None:
     777        raise Http404, "App %r, model %r, not found" % (app_label, model_name)
     778    opts = model._meta
     779    if not request.user.has_perm(app_label + '.' + opts.get_delete_permission()):
     780        raise PermissionDenied
     781    perms_needed = sets.Set()
     782    #Fetch all the objects
     783    objects = [get_object_or_404(model, pk = unquote(o)) for o in request.POST if o != "doit"]
     784
     785    perms_needed = sets.Set()
     786    for obj in objects:
     787        obj.deleted_objects = ['%s: <a href="../../%s/">%s</a>' % (capfirst(opts.verbose_name), getattr(obj,opts.pk.attname), escape(str(obj))), []]
     788        obj.deleteid = getattr(obj,opts.pk.attname)
     789        _get_deleted_objects(obj.deleted_objects, perms_needed, request.user, obj, opts, 1)
     790
     791    if request.POST.get('doit', 0): # The user has already confirmed the deletion.
     792        if perms_needed:
     793            raise PermissionDenied
     794        obj_display = []
     795        for obj in objects:
     796            obj_display.append(str(obj))
     797            obj.delete()
     798            LogEntry.objects.log_action(request.user.id, ContentType.objects.get_for_model(model).id, obj.deleteid, str(obj), DELETION)
     799        request.user.message_set.create(message=_('The %(name)s objects: "%(obj)s" were deleted successfully.') % {'name': opts.verbose_name, 'obj': ",".join(obj_display)})
     800        return HttpResponseRedirect("../")     
     801
     802    extra_context = {
     803        "title": _("Are you sure?"),
     804        "object_name": opts.verbose_name,
     805        "daobjects": objects,
     806        "perms_lacking": perms_needed,
     807        "opts": model._meta,
     808    }
     809    return render_to_response(["admin/%s/%s/deletelist_confirmation.html" % (app_label, opts.object_name.lower() ),
     810                               "admin/%s/deletelist_confirmation.html" % app_label ,
     811                               "admin/deletelist_confirmation.html"], extra_context, context_instance=template.RequestContext(request))
     812delete_checked = staff_member_required(delete_checked)
Back to Top