Fix for recent Django.

This commit is contained in:
Jannis Leidel 2021-03-09 13:14:40 +01:00
parent 245b5911e6
commit f5ee0d12c3
No known key found for this signature in database
GPG key ID: C795956FB489DCA9
8 changed files with 171 additions and 140 deletions

View file

@ -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<pk>\d+)/update/password/$',
name="dashboard",
),
re_path(
r"^auth/user/(?P<pk>\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<app_label>\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<app_label>\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

View file

@ -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)

View file

@ -49,7 +49,7 @@
</li>
{% endif %}
{% for link, date in dates %}
<li class="{% ifequal active_day date %}active{% endifequal %}">
<li class="{% if active_day == date %}active{% endif %}">
<a href="{{ link|safe }}">{{ date }}</a>
</li>
{% endfor %}

View file

@ -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<pk>[0-9]+)/$', views.ModelEditFormView, name='update')
detail_view = views.AdminView(r'^(?P<pk>[0-9]+)/update/$', views.ModelDetailView, name='detail')
delete_view = views.AdminView(r'^(?P<pk>[0-9]+)/delete/$', views.ModelDeleteView, name='delete')
history_view = views.AdminView(r'^(?P<pk>[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<pk>[0-9]+)/$", views.ModelEditFormView, name="update"
)
detail_view = views.AdminView(
r"^(?P<pk>[0-9]+)/update/$", views.ModelDetailView, name="detail"
)
delete_view = views.AdminView(
r"^(?P<pk>[0-9]+)/delete/$", views.ModelDeleteView, name="delete"
)
history_view = views.AdminView(
r"^(?P<pk>[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<pk>[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<pk>[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]
)

View file

@ -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<pk>\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<pk>\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)

View file

@ -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

View file

@ -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

View file

@ -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'],