- Author:
- kylefox
- Posted:
- May 26, 2007
- Language:
- HTML/template
- Version:
- Not specified
- Score:
- 10 (after 10 ratings)
This adds a checkbox for each object and three buttons to a model's change list:
-
Delete selected: deletes the selected objects
-
Delete shown: deletes all the visible objects. For example, if you perform a search or in any way filter the list, this button deletes only objects that were filtered.
-
Delete all: Deletes all instances of the model, including those not shown (if looking at a filtered list).
The deletes perform no confirmation -- once you hit the buttons the models are gone, so maybe don't use (or add a confirmation screen) for really sensitive stuff.
- uses django oldforms-admin (ie 0.96)
- works fine if you include a search_fields list in the Admin class
- code for the view could probably be refactored a bit :)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | ### MODEL: Include something like this in your model ###
class Person(models.Model):
class Admin:
list_display = ['name', 'select']
name = models.CharField(maxlength=100)
def select(self):
return '<input type="checkbox" name="person" value="%s"/>' % self.id
select.allow_tags = True
select.short_description = ''
### TEMPLATE: 'change_list.html' ###
### Put it in either admin/change_list.html, admin/<app>/<model>/change_list.html, etc ###
{% extends "admin/change_list.html" %}
{% block result_list %}
<form action="delete/" method="post">
{{ block.super }}
{% for r in cl.get_query_set %}
<input type="hidden" name="qs_obj" value="{{ r.id }}" id="qs_obj_{{ r.id }}">
{% endfor %}
<p>
<input type="submit" name="delete_selected" id="id_delete_selected" value="Delete selected" />
<input type="submit" name="delete_shown" id="id_delete_shown" value="Delete shown" />
<input type="submit" name="delete_all" id="id_delete_all" value="Delete all" />
</p>
</form>
{% endblock %}
### VIEW: I just tossed this in 'admin.py' in the project root ###
from django.contrib.admin.views.main import *
def delete(request, app_label, model_name):
model = models.get_model(app_label, model_name)
opts = model._meta
if model is None:
raise Http404("App %r, model %r, not found" % (app_label, model_name))
if not request.user.has_perm(app_label + '.' + model._meta.get_change_permission()):
raise PermissionDenied
try:
cl = ChangeList(request, model)
except IncorrectLookupParameters:
if ERROR_FLAG in request.GET.keys():
return render_to_response('admin/invalid_setup.html', {'title': _('Database error')})
return HttpResponseRedirect(request.path + '?' + ERROR_FLAG + '=1')
if 'delete_selected' in request.POST and model_name in request.POST:
deleted = []
for obj in cl.get_query_set().filter(id__in=request.POST.getlist(model_name)):
obj.delete()
deleted.append('"%s"' % str(obj))
request.user.message_set.create(message=_('The %(name)s %(obj)s were deleted successfully.') % {'name': opts.verbose_name_plural, 'obj': ", ".join(deleted)})
if 'delete_shown' in request.POST and 'qs_obj' in request.POST:
deleted = []
for obj in cl.get_query_set().filter(id__in=request.POST.getlist('qs_obj')):
obj.delete()
deleted.append('"%s"' % str(obj))
request.user.message_set.create(message=_('The %(name)s %(obj)s were deleted successfully.') % {'name': opts.verbose_name_plural, 'obj': ", ".join(deleted)})
if 'delete_all' in request.POST and cl.get_query_set().count() > 0:
for obj in cl.get_query_set():
obj.delete()
request.user.message_set.create(message=_('All %(name)s were deleted successfully.') % {'name': opts.verbose_name_plural})
return HttpResponseRedirect('..')
change_list = staff_member_required(never_cache(change_list))
### URLS: Add this line to your urls BEFORE the normal admin urls line ###
('^admin/([^/]+)/([^/]+)/delete/$', 'admin.delete'),
|
More like this
- Bootstrap Accordian by Netplay4 5 years, 11 months ago
- Bootstrap theme for django-endless-pagination? by se210 8 years, 11 months ago
- Bootstrap theme for django-endless-pagination? by se210 8 years, 11 months ago
- Reusable form template with generic view by roldandvg 9 years ago
- Pagination Django with Boostrap by guilegarcia 9 years, 2 months ago
Comments
On line 54, delete_selected seems to be failing on the condition "model_name in request.POST:". model_name doesn't appear anywhere in request.POST when I attempt to remove an item.
#
Ok, sorry I see what you did now: class Person(models.Model): return '<input type="checkbox" name="person" value="%s"/>' % self.id
You named the input checkbox the same as the model. My mistake.
#
I added a bit to your snippet to allow the user to select all and un-select all by use of a check box next to the Delete field and some Jquery. Here is the Jquery:
$("#checkboxall").click(function(){ var checked_status = this.checked; $("input[@name=person]").each(function(){ this.checked = checked_status; }); });
Then add this to the short description:select.short_description = 'Delete <input type="checkbox" id="checkboxall" name="check_all" value="Check All" />'
I thought this would help some people. Great snippet. Very useful.#
Sorry, short description should look like this:
select.short_description = 'Delete <input type="checkbox" id="checkboxall" name="check_all" value="Check All" />'
#
Lines 59, 66, and 71 generate this error with version .97: "global name '_' is not defined" I'm not very good with Python, so I'm not sure how to fix this. Any suggestions?
Also with my comment on using jQuery in short_description, you will have to use mark_safe() on that now, since autoescape defaults to on in .97. (from django.utils.safestring import mark_safe). Otherwise the html won't render properly.
#
I don't know python well enough to know why those lines were causing errors, but I changed it to: request.user.message_set.create(message="The %(name)s %(obj)s were deleted successfully." % {'name': opts.verbose_name_plural, 'obj': ", ".join(deleted)}) instead and it works.
#
Please login first before commenting.