Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
Changelog
=========

0.1.2
-----
* Bump up version
* Fix "Select all" issue

0.1.1
-----

Expand Down
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Django bulk admin enables you to bulk add, bulk edit, bulk upload and bulk selec

View the screenshots below to get an idea of how django bulk admin does look like.

Requires Django >= 1.11.
**This is a fork that is ahead of the master as my pull requests are not merged.** Supports Django 3 and 4. Seems to be working with Django 5.


===========
Expand Down
59 changes: 29 additions & 30 deletions bulk_admin/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
from django.contrib import admin, messages
from django.contrib.admin.exceptions import DisallowedModelAdminToField
from django.contrib.admin.options import IS_POPUP_VAR, InlineModelAdmin, TO_FIELD_VAR, csrf_protect_m
from django.contrib.admin.templatetags.admin_static import static
from django.contrib.admin.templatetags.admin_urls import add_preserved_filters
from django.contrib.admin.utils import NestedObjects, flatten_fieldsets
from django.core.exceptions import PermissionDenied, ValidationError
Expand All @@ -16,10 +15,10 @@
from django.http import HttpResponseRedirect
from django.template.response import SimpleTemplateResponse
from django.urls import reverse
from django.utils import six
from django.utils.encoding import force_text
from django.utils.encoding import force_str
from django.utils.text import get_text_list
from django.utils.translation import ugettext as _, ugettext_lazy
from django.utils.translation import gettext as _, gettext_lazy
from django.conf.urls.static import static
from functools import partial, update_wrapper

import django
Expand Down Expand Up @@ -65,7 +64,7 @@ def __init__(self, *args, **kwargs):
]

def get_urls(self):
from django.conf.urls import url
from django.urls import re_path

def wrap(view):
def wrapper(*args, **kwargs):
Expand All @@ -75,7 +74,7 @@ def wrapper(*args, **kwargs):
info = self.model._meta.app_label, self.model._meta.model_name

urlpatterns = super(BulkModelAdmin, self).get_urls()
urlpatterns.insert(0, url(r'^bulk/$', wrap(self.bulk_view), name='%s_%s_bulk' % info))
urlpatterns.insert(0, re_path(r'^bulk/$', wrap(self.bulk_view), name='%s_%s_bulk' % info))

return urlpatterns

Expand Down Expand Up @@ -158,7 +157,7 @@ def bulk_view(self, request, form_url='', extra_context=None):

formset = formset_class(**formset_params)

msg = _('The %s were bulk added successfully. You may edit them again below.') % (force_text(opts.verbose_name_plural),)
msg = _('The %s were bulk added successfully. You may edit them again below.') % (force_str(opts.verbose_name_plural),)
self.message_user(request, msg, messages.SUCCESS)

else:
Expand All @@ -175,23 +174,23 @@ def bulk_view(self, request, form_url='', extra_context=None):
if formset.is_bound:
errors.extend(formset.non_form_errors())
for formset_errors in formset.errors:
errors.extend(list(six.itervalues(formset_errors)))

context = dict(
self.admin_site.each_context(request) if django.VERSION >= (1, 8) else self.admin_site.each_context(),
bulk=True,
bulk_formset_prefix=prefix,
bulk_upload_fields=self.get_bulk_upload_fields(request),
title=_('Bulk add %s') % force_text(opts.verbose_name_plural),
is_popup=(IS_POPUP_VAR in request.POST or
errors.extend(list(iter(formset_errors.values())))

context = self.admin_site.each_context(request)
context.update({
'bulk': True,
'bulk_formset_prefix': prefix,
'bulk_upload_fields': self.get_bulk_upload_fields(request),
'title': _('Bulk add %s') % force_str(opts.verbose_name_plural),
'is_popup': (IS_POPUP_VAR in request.POST or
IS_POPUP_VAR in request.GET),
to_field=to_field,
media=media,
inline_admin_formsets=inline_formsets,
errors=errors,
preserved_filters=self.get_preserved_filters(request),
)

'to_field': to_field,
'media': media,
'inline_admin_formsets': inline_formsets,
'errors': errors,
'preserved_filters': self.get_preserved_filters(request),
'adminform': admin.helpers.AdminForm(ManagementForm(), [], {}),
})
context.update(extra_context or {})

return self.render_change_form(request, context, add=True, change=False, obj=None, form_url=form_url)
Expand All @@ -201,8 +200,8 @@ def response_bulk(self, request, formset):
opts = model._meta
preserved_filters = self.get_preserved_filters(request)
msg_dict = {
'name': force_text(opts.verbose_name),
'name_plural': force_text(opts.verbose_name_plural),
'name': force_str(opts.verbose_name),
'name_plural': force_str(opts.verbose_name_plural),
}

if IS_POPUP_VAR in request.POST:
Expand Down Expand Up @@ -273,7 +272,7 @@ def transform_post_and_files(self, request, prefix):
post.update({
'{}-{}-{}'.format(prefix, index, name): value
for name, value
in six.iteritems(form_data_for_file)
in iter(form_data_for_file.items())
})

return post, files, force_continue
Expand Down Expand Up @@ -312,25 +311,25 @@ def get_bulk_upload_fields(self, request):
@property
def media(self):
media = super(BulkModelAdmin, self).media
media.add_js([static('bulk_admin/js/bulk.js')])
media._js.extend([static('bulk_admin/js/bulk.js')])

return media

def select_related_action(self, request, queryset):
return self.response_bulk_popup(request, queryset)

select_related_action.short_description = ugettext_lazy('Select')
select_related_action.short_description = gettext_lazy('Select')

def bulk_edit_action(self, request, queryset):
model = self.model
opts = model._meta

selected = request.POST.getlist(admin.ACTION_CHECKBOX_NAME)
selected = queryset.values_list('pk', flat=True)
redirect_url = reverse('admin:%s_%s_bulk' % (opts.app_label, opts.model_name), current_app=self.admin_site.name)

return HttpResponseRedirect('{}?pks={}'.format(redirect_url, ','.join(selected)))

bulk_edit_action.short_description = ugettext_lazy('Bulk edit')
bulk_edit_action.short_description = gettext_lazy('Bulk edit')


class BulkInlineModelAdmin(InlineModelAdmin):
Expand Down
18 changes: 7 additions & 11 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,17 @@

setup(
name='django-bulk-admin',
version='0.1.1',
version='0.1.2',
packages=find_packages(exclude=('example_project*', 'screenshots',)),
include_package_data=True,
license='BSD',
description='Django bulk admin enables you to bulk add, bulk edit, bulk upload and bulk select in django admin.',
long_description=README,
url='https://github.com/purelabs/django-bulk-admin',
author='Ruben Grill',
url='https://github.com/jameslao/django-bulk-admin',
author='Ruben Grill, James Lao',
author_email='ruben.grill@gmail.com',
install_requires=[
'Django>=1.11',
'Django>=4.0',
],
classifiers=[
'Environment :: Web Environment',
Expand All @@ -28,13 +28,9 @@
'License :: OSI Approved :: BSD License',
'Operating System :: OS Independent',
'Programming Language :: Python',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.10',
'Programming Language :: Python :: 3.11',
'Programming Language :: Python :: 3.12',
'Topic :: Software Development :: Libraries :: Python Modules',
],
)