diff --git a/wagtail/wagtailadmin/urls/__init__.py b/wagtail/wagtailadmin/urls/__init__.py index 31a80d8d97..089a4eddb8 100644 --- a/wagtail/wagtailadmin/urls/__init__.py +++ b/wagtail/wagtailadmin/urls/__init__.py @@ -5,12 +5,16 @@ from wagtail.wagtailadmin.urls import pages as wagtailadmin_pages_urls from wagtail.wagtailadmin.urls import collections as wagtailadmin_collections_urls from wagtail.wagtailadmin.urls import password_reset as wagtailadmin_password_reset_urls from wagtail.wagtailadmin.views import account, chooser, home, pages, tags, userbar +from wagtail.wagtailadmin.viewsets import register_viewsets from wagtail.wagtailadmin.api import urls as api_urls from wagtail.wagtailcore import hooks from wagtail.utils.urlpatterns import decorate_urlpatterns from wagtail.wagtailadmin.decorators import require_admin_access +register_viewsets() + + urlpatterns = [ url(r'^$', home.home, name='wagtailadmin_home'), diff --git a/wagtail/wagtailadmin/viewsets/__init__.py b/wagtail/wagtailadmin/viewsets/__init__.py new file mode 100644 index 0000000000..dd6e30afe4 --- /dev/null +++ b/wagtail/wagtailadmin/viewsets/__init__.py @@ -0,0 +1,21 @@ +from django.conf.urls import url, include + +from wagtail.wagtailcore import hooks + + +def register_viewsets(): + for fn in hooks.get_hooks('register_admin_viewset'): + viewset = fn() + + if viewset: + urlpatterns = viewset.get_urlpatterns() + + if urlpatterns: + @hooks.register('register_admin_urls') + def register_admin_urls(): + return [ + url( + r'^{}/'.format(viewset.name), + include(urlpatterns, app_name=viewset.name, namespace=viewset.name) + ), + ] diff --git a/wagtail/wagtailadmin/viewsets/base.py b/wagtail/wagtailadmin/viewsets/base.py new file mode 100644 index 0000000000..a282bd6a18 --- /dev/null +++ b/wagtail/wagtailadmin/viewsets/base.py @@ -0,0 +1,12 @@ +from __future__ import absolute_import, unicode_literals + + +class ViewSet(object): + def __init__(self, name, **kwargs): + self.name = name + + for key, value in kwargs.items(): + setattr(self, key, value) + + def get_urlpatterns(self): + return [] diff --git a/wagtail/wagtailadmin/viewsets/model.py b/wagtail/wagtailadmin/viewsets/model.py new file mode 100644 index 0000000000..b7cc82fedf --- /dev/null +++ b/wagtail/wagtailadmin/viewsets/model.py @@ -0,0 +1,88 @@ +from __future__ import absolute_import, unicode_literals + +from django.conf.urls import url +from django.forms.models import modelform_factory + +from wagtail.wagtailadmin.views import generic +from wagtail.wagtailcore.permissions import ModelPermissionPolicy + +from .base import ViewSet + + +class ModelViewSet(ViewSet): + icon = "" + + index_view_class = generic.IndexView + add_view_class = generic.CreateView + edit_view_class = generic.EditView + delete_view_class = generic.DeleteView + + def get_url_name(self, view_name): + return self.name + ':' + view_name + + @property + def permission_policy(self): + return ModelPermissionPolicy(self.model) + + @property + def index_view(self): + return self.index_view_class.as_view( + model=self.model, + permission_policy=self.permission_policy, + index_url_name=self.get_url_name('index'), + add_url_name=self.get_url_name('add'), + edit_url_name=self.get_url_name('edit'), + header_icon=self.icon, + ) + + @property + def add_view(self): + return self.add_view_class.as_view( + model=self.model, + permission_policy=self.permission_policy, + form_class=self.get_form_class(), + index_url_name=self.get_url_name('index'), + add_url_name=self.get_url_name('add'), + edit_url_name=self.get_url_name('edit'), + header_icon=self.icon, + ) + + @property + def edit_view(self): + return self.edit_view_class.as_view( + model=self.model, + permission_policy=self.permission_policy, + form_class=self.get_form_class(for_update=True), + index_url_name=self.get_url_name('index'), + edit_url_name=self.get_url_name('edit'), + delete_url_name=self.get_url_name('delete'), + header_icon=self.icon, + ) + + @property + def delete_view(self): + return self.delete_view_class.as_view( + model=self.model, + permission_policy=self.permission_policy, + index_url_name=self.get_url_name('index'), + delete_url_name=self.get_url_name('delete'), + header_icon=self.icon, + ) + + def formfield_for_dbfield(self, db_field, **kwargs): + return db_field.formfield(**kwargs) + + def get_form_class(self, for_update=False): + return modelform_factory( + self.model, + formfield_callback=self.formfield_for_dbfield, + fields='__all__' + ) + + def get_urlpatterns(self): + return [ + url(r'^$', self.index_view, name='index'), + url(r'^new/$', self.add_view, name='add'), + url(r'^(\d+)/$', self.edit_view, name='edit'), + url(r'^(\d+)/delete/$', self.delete_view, name='delete'), + ]