From f5ee0d12c34b6d7ec3b84b92a6a9fff14555f6a9 Mon Sep 17 00:00:00 2001 From: Jannis Leidel Date: Tue, 9 Mar 2021 13:14:40 +0100 Subject: [PATCH] Fix for recent Django. --- djadmin2/core.py | 108 ++++++------ djadmin2/tests/urls.py | 4 +- .../djadmin2theme_bootstrap3/model_list.html | 2 +- djadmin2/types.py | 159 ++++++++++-------- example/example/urls.py | 22 ++- example/files/admin2.py | 2 - requirements.txt | 13 +- setup.py | 1 - 8 files changed, 171 insertions(+), 140 deletions(-) diff --git a/djadmin2/core.py b/djadmin2/core.py index 790d581..8754e38 100644 --- a/djadmin2/core.py +++ b/djadmin2/core.py @@ -5,7 +5,7 @@ Issue #99. from importlib import import_module from django.conf import settings -from django.conf.urls import url +from django.urls import re_path from django.core.exceptions import ImproperlyConfigured from . import apiviews @@ -23,12 +23,13 @@ class Admin2(object): It also provides an index view that serves as an entry point to the admin site. """ + index_view = views.IndexView login_view = views.LoginView app_index_view = views.AppIndexView api_index_view = apiviews.IndexAPIView - def __init__(self, name='admin2'): + def __init__(self, name="admin2"): self.registry = {} self.apps = {} self.app_verbose_names = {} @@ -48,7 +49,8 @@ class Admin2(object): """ if model in self.registry: raise ImproperlyConfigured( - '%s is already registered in django-admin2' % model) + "%s is already registered in django-admin2" % model + ) if not model_admin: model_admin = types.ModelAdmin2 self.registry[model] = model_admin(model, admin=self, **kwargs) @@ -71,7 +73,8 @@ class Admin2(object): del self.registry[model] except KeyError: raise ImproperlyConfigured( - '%s was never registered in django-admin2' % model) + "%s was never registered in django-admin2" % model + ) # Remove the model from the apps registry # Get the app label @@ -93,7 +96,8 @@ class Admin2(object): """ if app_label in self.app_verbose_names: raise ImproperlyConfigured( - '%s is already registered in django-admin2' % app_label) + "%s is already registered in django-admin2" % app_label + ) self.app_verbose_names[app_label] = app_verbose_name @@ -109,7 +113,8 @@ class Admin2(object): del self.app_verbose_names[app_label] except KeyError: raise ImproperlyConfigured( - '%s app label was never registered in django-admin2' % app_label) + "%s app label was never registered in django-admin2" % app_label + ) def autodiscover(self): """ @@ -120,7 +125,7 @@ class Admin2(object): try: import_module("%s.admin2" % app_name) except ImportError as e: - if str(e).startswith("No module named") and 'admin2' in str(e): + if str(e).startswith("No module named") and "admin2" in str(e): continue raise e @@ -132,71 +137,74 @@ class Admin2(object): for object_admin in self.registry.values(): if object_admin.name == name: return object_admin - raise ValueError( - u'No object admin found with name {}'.format(repr(name))) + raise ValueError(u"No object admin found with name {}".format(repr(name))) def get_index_kwargs(self): return { - 'registry': self.registry, - 'app_verbose_names': self.app_verbose_names, - 'apps': self.apps, - 'login_view': self.login_view, + "registry": self.registry, + "app_verbose_names": self.app_verbose_names, + "apps": self.apps, + "login_view": self.login_view, } def get_app_index_kwargs(self): return { - 'registry': self.registry, - 'app_verbose_names': self.app_verbose_names, - 'apps': self.apps, + "registry": self.registry, + "app_verbose_names": self.app_verbose_names, + "apps": self.apps, } def get_api_index_kwargs(self): return { - 'registry': self.registry, - 'app_verbose_names': self.app_verbose_names, - 'apps': self.apps, + "registry": self.registry, + "app_verbose_names": self.app_verbose_names, + "apps": self.apps, } def get_urls(self): urlpatterns = [ - url(regex=r'^$', + re_path( + r"^$", view=self.index_view.as_view(**self.get_index_kwargs()), - name='dashboard' - ), - url(regex=r'^auth/user/(?P\d+)/update/password/$', + name="dashboard", + ), + re_path( + r"^auth/user/(?P\d+)/update/password/$", view=views.PasswordChangeView.as_view(), - name='password_change' - ), - url(regex='^password_change_done/$', + name="password_change", + ), + re_path( + "^password_change_done/$", view=views.PasswordChangeDoneView.as_view(), - name='password_change_done' - ), - url(regex='^logout/$', - view=views.LogoutView.as_view(), - name='logout' - ), - url(regex=r'^(?P\w+)/$', - view=self.app_index_view.as_view( - **self.get_app_index_kwargs()), - name='app_index' - ), - url(regex=r'^api/v0/$', - view=self.api_index_view.as_view( - **self.get_api_index_kwargs()), - name='api_index' - ), + name="password_change_done", + ), + re_path("^logout/$", view=views.LogoutView.as_view(), name="logout"), + re_path( + r"^(?P\w+)/$", + view=self.app_index_view.as_view(**self.get_app_index_kwargs()), + name="app_index", + ), + re_path( + r"^api/v0/$", + view=self.api_index_view.as_view(**self.get_api_index_kwargs()), + name="api_index", + ), ] for model, model_admin in self.registry.items(): model_options = utils.model_options(model) urlpatterns += [ - url('^{}/{}/'.format( - model_options.app_label, - model_options.object_name.lower()), - model_admin.urls), - url('^api/v0/{}/{}/'.format( - model_options.app_label, - model_options.object_name.lower()), - model_admin.api_urls), + re_path( + "^{}/{}/".format( + model_options.app_label, model_options.object_name.lower() + ), + model_admin.urls, + ), + re_path( + "^api/v0/{}/{}/".format( + model_options.app_label, model_options.object_name.lower() + ), + model_admin.api_urls, + ), ] return urlpatterns diff --git a/djadmin2/tests/urls.py b/djadmin2/tests/urls.py index bb5e960..1ade7cc 100644 --- a/djadmin2/tests/urls.py +++ b/djadmin2/tests/urls.py @@ -1,6 +1,6 @@ from django.conf import settings -from django.conf.urls import url from django.conf.urls.static import static +from django.urls import re_path from djadmin2.site import djadmin2_site @@ -15,5 +15,5 @@ djadmin2_site.login_view = CustomLoginView djadmin2_site.autodiscover() urlpatterns = [ - url(r'^admin2/', djadmin2_site.urls), + re_path(r'^admin2/', djadmin2_site.urls), ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) diff --git a/djadmin2/themes/djadmin2theme_bootstrap3/templates/djadmin2theme_bootstrap3/model_list.html b/djadmin2/themes/djadmin2theme_bootstrap3/templates/djadmin2theme_bootstrap3/model_list.html index f3e6d75..3b0aad6 100644 --- a/djadmin2/themes/djadmin2theme_bootstrap3/templates/djadmin2theme_bootstrap3/model_list.html +++ b/djadmin2/themes/djadmin2theme_bootstrap3/templates/djadmin2theme_bootstrap3/model_list.html @@ -49,7 +49,7 @@ {% endif %} {% for link, date in dates %} -
  • +
  • {{ date }}
  • {% endfor %} diff --git a/djadmin2/types.py b/djadmin2/types.py index d20343a..94b2c1a 100644 --- a/djadmin2/types.py +++ b/djadmin2/types.py @@ -4,9 +4,8 @@ import sys from collections import namedtuple import extra_views -from django.conf.urls import url from django.forms import modelform_factory -from django.urls import reverse +from django.urls import re_path, reverse from . import actions from . import apiviews @@ -15,14 +14,12 @@ from . import utils from . import views -logger = logging.getLogger('djadmin2') +logger = logging.getLogger("djadmin2") class ModelAdminBase2(type): - def __new__(cls, name, bases, attrs): - new_class = super(ModelAdminBase2, cls).__new__(cls, name, - bases, attrs) + new_class = super(ModelAdminBase2, cls).__new__(cls, name, bases, attrs) view_list = [] for key, value in attrs.items(): if isinstance(value, views.AdminView): @@ -30,7 +27,7 @@ class ModelAdminBase2(type): value.name = key view_list.append(value) - view_list.extend(getattr(new_class, 'views', [])) + view_list.extend(getattr(new_class, "views", [])) new_class.views = view_list return new_class @@ -54,9 +51,10 @@ class ModelAdmin2(metaclass=ModelAdminBase2): This prevents us from easily implementing methods/setters which bypass the blocking features of the ImmutableAdmin. """ + actions_selection_counter = True date_hierarchy = False - list_display = ('__str__',) + list_display = ("__str__",) list_display_links = () list_filter = () list_select_related = False @@ -113,12 +111,20 @@ class ModelAdmin2(metaclass=ModelAdminBase2): inlines = [] # Views - index_view = views.AdminView(r'^$', views.ModelListView, name='index') - create_view = views.AdminView(r'^create/$', views.ModelAddFormView, name='create') - update_view = views.AdminView(r'^(?P[0-9]+)/$', views.ModelEditFormView, name='update') - detail_view = views.AdminView(r'^(?P[0-9]+)/update/$', views.ModelDetailView, name='detail') - delete_view = views.AdminView(r'^(?P[0-9]+)/delete/$', views.ModelDeleteView, name='delete') - history_view = views.AdminView(r'^(?P[0-9]+)/history/$', views.ModelHistoryView, name='history') + index_view = views.AdminView(r"^$", views.ModelListView, name="index") + create_view = views.AdminView(r"^create/$", views.ModelAddFormView, name="create") + update_view = views.AdminView( + r"^(?P[0-9]+)/$", views.ModelEditFormView, name="update" + ) + detail_view = views.AdminView( + r"^(?P[0-9]+)/update/$", views.ModelDetailView, name="detail" + ) + delete_view = views.AdminView( + r"^(?P[0-9]+)/delete/$", views.ModelDeleteView, name="delete" + ) + history_view = views.AdminView( + r"^(?P[0-9]+)/history/$", views.ModelHistoryView, name="history" + ) views = [] # API configuration @@ -137,7 +143,7 @@ class ModelAdmin2(metaclass=ModelAdminBase2): self.model_name = model_options.object_name.lower() if self.name is None: - self.name = '{}_{}'.format(self.app_label, self.model_name) + self.name = "{}_{}".format(self.app_label, self.model_name) if self.verbose_name is None: self.verbose_name = model_options.verbose_name @@ -146,60 +152,73 @@ class ModelAdmin2(metaclass=ModelAdminBase2): def get_default_view_kwargs(self): return { - 'app_label': self.app_label, - 'model': self.model, - 'model_name': self.model_name, - 'model_admin': immutable_admin_factory(self), + "app_label": self.app_label, + "model": self.model, + "model_name": self.model_name, + "model_admin": immutable_admin_factory(self), } def get_index_kwargs(self): kwargs = self.get_default_view_kwargs() - kwargs.update({ - 'paginate_by': self.list_per_page, - }) + kwargs.update( + { + "paginate_by": self.list_per_page, + } + ) return kwargs def get_default_api_view_kwargs(self): kwargs = self.get_default_view_kwargs() - kwargs.update({ - 'serializer_class': self.api_serializer_class, - }) + kwargs.update( + { + "serializer_class": self.api_serializer_class, + } + ) return kwargs def get_prefixed_view_name(self, view_name): - return '{}_{}'.format(self.name, view_name) + return "{}_{}".format(self.name, view_name) def get_create_kwargs(self): kwargs = self.get_default_view_kwargs() - kwargs.update({ - 'inlines': self.inlines, - 'form_class': (self.create_form_class if - self.create_form_class else self.form_class), - }) + kwargs.update( + { + "inlines": self.inlines, + "form_class": ( + self.create_form_class + if self.create_form_class + else self.form_class + ), + } + ) return kwargs def get_update_kwargs(self): kwargs = self.get_default_view_kwargs() - form_class = (self.update_form_class if - self.update_form_class else self.form_class) + form_class = ( + self.update_form_class if self.update_form_class else self.form_class + ) if form_class is None: - form_class = modelform_factory(self.model, fields='__all__') - kwargs.update({ - 'inlines': self.inlines, - 'form_class': form_class, - }) + form_class = modelform_factory(self.model, fields="__all__") + kwargs.update( + { + "inlines": self.inlines, + "form_class": form_class, + } + ) return kwargs def get_index_url(self): - return reverse('admin2:{}'.format( - self.get_prefixed_view_name('index'))) + return reverse("admin2:{}".format(self.get_prefixed_view_name("index"))) def get_api_list_kwargs(self): kwargs = self.get_default_api_view_kwargs() - kwargs.update({ - 'queryset': self.model.objects.all(), - # 'paginate_by': self.list_per_page, - }) + kwargs.update( + { + "queryset": self.model.objects.all(), + # 'paginate_by': self.list_per_page, + } + ) return kwargs def get_api_detail_kwargs(self): @@ -218,34 +237,35 @@ class ModelAdmin2(metaclass=ModelAdminBase2): trace = sys.exc_info()[2] new_exception = TypeError( 'Cannot instantiate admin view "{}.{}". ' - 'The error that got raised was: {}'.format( - self.__class__.__name__, admin_view.name, e)) + "The error that got raised was: {}".format( + self.__class__.__name__, admin_view.name, e + ) + ) try: raise new_exception.with_traceback(trace) except AttributeError: raise (new_exception, None, trace) pattern_list.append( - url( - regex=admin_view.url, + re_path( + admin_view.url, view=view_instance, - name=self.get_prefixed_view_name(admin_view.name) + name=self.get_prefixed_view_name(admin_view.name), ) ) return pattern_list def get_api_urls(self): return [ - url( - regex=r'^$', + re_path( + r"^$", view=self.api_list_view.as_view(**self.get_api_list_kwargs()), - name=self.get_prefixed_view_name('api_list'), + name=self.get_prefixed_view_name("api_list"), ), - url( - regex=r'^(?P[0-9]+)/$', - view=self.api_detail_view.as_view( - **self.get_api_detail_kwargs()), - name=self.get_prefixed_view_name('api_detail'), + re_path( + r"^(?P[0-9]+)/$", + view=self.api_detail_view.as_view(**self.get_api_detail_kwargs()), + name=self.get_prefixed_view_name("api_detail"), ), ] @@ -262,12 +282,12 @@ class ModelAdmin2(metaclass=ModelAdminBase2): actions_dict = {} for cls in type(self).mro()[::-1]: - class_actions = getattr(cls, 'list_actions', []) + class_actions = getattr(cls, "list_actions", []) for action in class_actions: actions_dict[action.__name__] = { - 'name': action.__name__, - 'description': actions.get_description(action), - 'action_callable': action + "name": action.__name__, + "description": actions.get_description(action), + "action_callable": action, } return actions_dict @@ -280,8 +300,9 @@ class Admin2Inline(extra_views.InlineFormSetFactory): A simple extension of django-extra-view's InlineFormSet that adds some useful functionality. """ + template = None - fields = '__all__' + fields = "__all__" def construct_formset(self): """ @@ -296,12 +317,14 @@ class Admin2Inline(extra_views.InlineFormSetFactory): class Admin2TabularInline(Admin2Inline): template = os.path.join( - settings.ADMIN2_THEME_DIRECTORY, 'edit_inlines/tabular.html') + settings.ADMIN2_THEME_DIRECTORY, "edit_inlines/tabular.html" + ) class Admin2StackedInline(Admin2Inline): template = os.path.join( - settings.ADMIN2_THEME_DIRECTORY, 'edit_inlines/stacked.html') + settings.ADMIN2_THEME_DIRECTORY, "edit_inlines/stacked.html" + ) def immutable_admin_factory(model_admin): @@ -315,7 +338,7 @@ def immutable_admin_factory(model_admin): the result, but hopefully developers attempting that 'workaround/hack' will read our documentation. """ - ImmutableAdmin = namedtuple('ImmutableAdmin', - model_admin.model_admin_attributes) - return ImmutableAdmin(*[getattr( - model_admin, x) for x in model_admin.model_admin_attributes]) + ImmutableAdmin = namedtuple("ImmutableAdmin", model_admin.model_admin_attributes) + return ImmutableAdmin( + *[getattr(model_admin, x) for x in model_admin.model_admin_attributes] + ) diff --git a/example/example/urls.py b/example/example/urls.py index 21655bb..50a1106 100644 --- a/example/example/urls.py +++ b/example/example/urls.py @@ -1,8 +1,8 @@ from blog.views import BlogListView, BlogDetailView from django.conf import settings -from django.conf.urls import url from django.conf.urls.static import static from django.contrib import admin +from django.urls import re_path from djadmin2.site import djadmin2_site @@ -10,13 +10,17 @@ from djadmin2.site import djadmin2_site djadmin2_site.autodiscover() urlpatterns = [ - url(r'^admin2/', djadmin2_site.urls), - url(r'^admin/', admin.site.urls), - url(r'^blog/', BlogListView.as_view(template_name="blog/blog_list.html"), - name='blog_list'), - url(r'^blog/detail(?P\d+)/$', + re_path(r"^admin2/", djadmin2_site.urls), + re_path(r"^admin/", admin.site.urls), + re_path( + r"^blog/", + BlogListView.as_view(template_name="blog/blog_list.html"), + name="blog_list", + ), + re_path( + r"^blog/detail(?P\d+)/$", BlogDetailView.as_view(template_name="blog/blog_detail.html"), - name='blog_detail'), - url(r'^$', BlogListView.as_view(template_name="blog/home.html"), - name='home'), + name="blog_detail", + ), + re_path(r"^$", BlogListView.as_view(template_name="blog/home.html"), name="home"), ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) diff --git a/example/files/admin2.py b/example/files/admin2.py index 1a029e9..85be47a 100644 --- a/example/files/admin2.py +++ b/example/files/admin2.py @@ -1,6 +1,4 @@ # -*- coding: utf-8 -*- -from __future__ import division, absolute_import, unicode_literals - from djadmin2.site import djadmin2_site from .models import CaptionedFile, UncaptionedFile diff --git a/requirements.txt b/requirements.txt index 1c4cc38..b8e946b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,6 @@ -django-extra-views==0.12.0 -django-braces==1.14.0 -djangorestframework==3.11.1 -django-filter==2.3.0 -django-debug-toolbar>=1.10.1 -future>=0.15.2 -pytz>=2016.4 +django-extra-views +django-braces +djangorestframework +django-filter +django-debug-toolbar +pytz diff --git a/setup.py b/setup.py index 7851de5..a5f9cef 100644 --- a/setup.py +++ b/setup.py @@ -136,7 +136,6 @@ setup( 'djangorestframework>=3.11.1', 'django-filter==2.3.0', 'pytz>=2016.4', - 'future>=0.15.2', ], extras_require={ 'testing': ['pytest', 'pytest-django', 'pytest-ipdb'],