diff --git a/crud/base.py b/crud/base.py index ea9f9c109..c3d0ec006 100644 --- a/crud/base.py +++ b/crud/base.py @@ -104,6 +104,10 @@ class BaseMixin(CrispyLayoutFormMixin): class CrudListView(ListView): + @classmethod + def get_url_regex(cls): + return r'^$' + paginate_by = 10 no_entries_msg = _('Nenhum registro encontrado.') @@ -142,6 +146,10 @@ class CrudListView(ListView): class CrudCreateView(FormMessagesMixin, CreateView): + @classmethod + def get_url_regex(cls): + return r'^create$' + form_valid_message, form_invalid_message = FORM_MESSAGES[CREATE] @property @@ -157,8 +165,19 @@ class CrudCreateView(FormMessagesMixin, CreateView): return super(CrudCreateView, self).get_context_data(**kwargs) +class CrudDetailView(DetailView): + + @classmethod + def get_url_regex(cls): + return r'^(?P\d+)$' + + class CrudUpdateView(FormMessagesMixin, UpdateView): + @classmethod + def get_url_regex(cls): + return r'^(?P\d+)/edit$' + form_valid_message, form_invalid_message = FORM_MESSAGES[UPDATE] @property @@ -171,6 +190,10 @@ class CrudUpdateView(FormMessagesMixin, UpdateView): class CrudDeleteView(FormMessagesMixin, DeleteView): + @classmethod + def get_url_regex(cls): + return r'^(?P\d+)/delete$' + form_valid_message, form_invalid_message = FORM_MESSAGES[DELETE] @property @@ -185,7 +208,7 @@ class Crud: BaseMixin = BaseMixin ListView = CrudListView CreateView = CrudCreateView - DetailView = DetailView + DetailView = CrudDetailView UpdateView = CrudUpdateView DeleteView = CrudDeleteView help_path = '' @@ -208,11 +231,12 @@ class Crud: return [url(regex, view.as_view(), name=view.url_name(suffix)) for regex, view, suffix in [ - (r'^$', CrudListView, LIST), - (r'^create$', CrudCreateView, CREATE), - (r'^(?P\d+)$', CrudDetailView, DETAIL), - (r'^(?P\d+)/edit$', CrudUpdateView, UPDATE), - (r'^(?P\d+)/delete$', CrudDeleteView, DELETE), ]] + (CrudListView.get_url_regex(), CrudListView, LIST), + (CrudCreateView.get_url_regex(), CrudCreateView, CREATE), + (CrudDetailView.get_url_regex(), CrudDetailView, DETAIL), + (CrudUpdateView.get_url_regex(), CrudUpdateView, UPDATE), + (CrudDeleteView.get_url_regex(), CrudDeleteView, DELETE), + ]] @classonlymethod def build(cls, _model, _help_path): diff --git a/crud/masterdetail.py b/crud/masterdetail.py new file mode 100644 index 000000000..458f74fd8 --- /dev/null +++ b/crud/masterdetail.py @@ -0,0 +1,35 @@ +from .base import (Crud, CrudCreateView, CrudDeleteView, CrudDetailView, + CrudListView, CrudUpdateView) + + +class MasterDetailCrud(Crud): + + class ListView(CrudListView): + + @classmethod + def get_url_regex(cls): + return r'^(?P\d+)/%s$' % cls.model._meta.model_name + + class CreateView(CrudCreateView): + + @classmethod + def get_url_regex(cls): + return r'^(?P\d+)/%s/create$' % cls.model._meta.model_name + + class DetailView(CrudDetailView): + + @classmethod + def get_url_regex(cls): + return r'^%s/(?P\d+)$' % cls.model._meta.model_name + + class UpdateView(CrudUpdateView): + + @classmethod + def get_url_regex(cls): + return r'^%s/(?P\d+)/edit$' % cls.model._meta.model_name + + class DeleteView(CrudDeleteView): + + @classmethod + def get_url_regex(cls): + return r'^%s/(?P\d+)/delete$' % cls.model._meta.model_name diff --git a/crud/tests/stub_app/models.py b/crud/tests/stub_app/models.py index 5540eea7c..1aab8779c 100644 --- a/crud/tests/stub_app/models.py +++ b/crud/tests/stub_app/models.py @@ -21,3 +21,8 @@ class Country(models.Model): def __str__(self): return self.name + + +class City(models.Model): + name = models.CharField(max_length=50) + country = models.ForeignKey(Country) diff --git a/crud/tests/stub_app/urls.py b/crud/tests/stub_app/urls.py index 623f167bf..99818018d 100644 --- a/crud/tests/stub_app/urls.py +++ b/crud/tests/stub_app/urls.py @@ -1,7 +1,8 @@ from django.conf.urls import include, url -from .views import CountryCrud +from .views import CityCrud, CountryCrud urlpatterns = [ - url(r'^country/', include(CountryCrud.get_urls(), 'stub_app')), + url(r'^country/', include( + CountryCrud.get_urls() + CityCrud.get_urls(), 'stub_app')), ] diff --git a/crud/tests/stub_app/views.py b/crud/tests/stub_app/views.py index 315397696..cd63fb7f1 100644 --- a/crud/tests/stub_app/views.py +++ b/crud/tests/stub_app/views.py @@ -1,6 +1,7 @@ from crud.base import Crud, CrudListView +from crud.masterdetail import MasterDetailCrud -from .models import Country +from .models import City, Country class CountryCrud(Crud): @@ -9,3 +10,8 @@ class CountryCrud(Crud): class ListView(CrudListView): paginate_by = 10 + + +class CityCrud(MasterDetailCrud): + model = City + help_path = 'help_path', diff --git a/crud/tests/test_masterdetail.py b/crud/tests/test_masterdetail.py new file mode 100644 index 000000000..b9d0d8ade --- /dev/null +++ b/crud/tests/test_masterdetail.py @@ -0,0 +1,14 @@ +import pytest +from django.core.urlresolvers import reverse + + +@pytest.mark.parametrize('path_name', [ + '/country/1/city stub_app:city_list', + '/country/1/city/create stub_app:city_create', + '/country/city/1 stub_app:city_detail', + '/country/city/1/edit stub_app:city_update', + '/country/city/1/delete stub_app:city_delete', +]) +def test_reverse(path_name): + path, name = path_name.split() + assert path == reverse(name, args=(1,))