فهرست منبع

Registering functions moved to register.py, uneeded data removed, several bugfixes.

Marcos Dumay de Medeiros 9 سال پیش
والد
کامیت
6bdaa55ca3

+ 0 - 1
src/rapid/models.py

@@ -12,7 +12,6 @@ class Application(models.Model):
     name = models.CharField(max_length=60, unique=True, verbose_name=u"nome")
     python_name = models.CharField(max_length=255, unique=True, verbose_name=u"Nome no Python")
     managers = models.ManyToManyField(User, verbose_name=u"gestores", related_name='managed_applications')
-    url = models.CharField(max_length=255, unique=True)
     enabled = models.BooleanField(default=True, verbose_name=u"ativa")
 
     def __unicode__(self):

+ 59 - 0
src/rapid/register.py

@@ -0,0 +1,59 @@
+__author__ = 'marcos'
+
+from rapid.views import bare_or_main, ListView, ReadView, UpdateView, CreateView, SelectView, DeleteView,\
+    update_form_class
+from rapid import permissions
+from rapid.registry import Action, MenuEntry, registry
+
+
+def _rvw(view_class, action_name):
+    view_class.action_name = action_name
+
+    def vw(model):
+        return bare_or_main(view_class.as_view(model=model))
+    return vw
+
+
+_default_actions = [
+    (False, Action("list", "", [], _rvw(ListView, 'list'), "listar", "fa-list")),
+    (False, Action("view", "(?P<pk>[0-9]+)", ['pk'], _rvw(ReadView, 'view'), "ver", "fa-eye")),
+    (True, Action("edit", "(?P<pk>[0-9]+)", ['pk'], _rvw(UpdateView, 'edit'), "editar", "fa-pencil")),
+    (True, Action("add", "", [], _rvw(CreateView, 'add'), "adicionar", "fa-plus")),
+    (False, Action("select", "", [], _rvw(SelectView, 'select'), "selecionar", "fa-hand-o-up",
+                   visibility=Action.Visibility.hidden)),
+]
+
+
+def model(model, read_set, write_set, actions=None, url_name=None, can_erase=False):
+    if actions:
+        actions = [(edt, a) for edt, a in _default_actions if a.name in actions]
+    else:
+        actions = _default_actions
+    ret = []
+    for edt, a in actions:
+        if edt:
+            ret.append(registry.register_action(a, MenuEntry(model, write_set, url_name=url_name)))
+        else:
+            ret.append(registry.register_action(a, MenuEntry(model, read_set, url_name=url_name)))
+    if can_erase:
+        a =  Action("delete", "(?P<pk>[0-9]+)", ['pk'], _rvw(DeleteView, 'delete'), "apagar", "fa-trash-o")
+        ret.append(registry.register_action(a, MenuEntry(model, write_set, url_name=url_name)))
+    return [u for u in ret if u]
+
+
+def instance_form(model, action_name, entry_name, form, permission_set, url_name=None, icon=None, visibility=None):
+    if not icon:
+        icon = ''
+    a = Action(action_name, "(?P<pk>[0-9]+)", ['pk'], _rvw(update_form_class(form), action_name),
+               entry_name, icon, visibility)
+    u = registry.register_action(a, MenuEntry(model, permission_set, url_name=url_name))
+    return [u] if u else []
+
+
+def select(model, visible_fields, permission_set, url_name=None):
+    class Vw(SelectView):
+        fields = visible_fields
+    a = Action("select", "", [], _rvw(Vw, 'select'), "selecionar", "fa-hand-o-up",
+               visibility=Action.Visibility.hidden)
+    u = registry.register_action(a, MenuEntry(model, permission_set, url_name=url_name))
+    return [u] if u else []

+ 10 - 11
src/rapid/registry.py

@@ -35,17 +35,17 @@ class MenuEntry:
     The data that goes on a menu item.
     Model, permissions and url
     """
-    def __init__(self, model, permission_set, name=None):
-        self.name = name
+    def __init__(self, model, permission, url_name=None):
+        self.url_name = url_name
         self.model = model
-        self.permission_set = permission_set
+        self.permission = permission
 
     def get_url(self, instance=None):
         ats = [(x, getattr(instance, x)) for x in self.action.query_parameters]
         return reverse(self.url, kwargs=dict(ats))
 
     def __unicode__(self):
-        return u"Menu entry: " + self.name + " -> " + unicode(self.action)
+        return u"Menu entry: " + self.url_name + " -> " + unicode(self.action)
 
     def __str__(self):
         return str(unicode(self))
@@ -55,10 +55,9 @@ class ModuleEntry:
     """
     Module data used at menu construction
     """
-    def __init__(self, python_name, menu_name, base_url):
+    def __init__(self, python_name, menu_name):
         self.python_name = python_name
         self.menu_name = menu_name
-        self.base_url = url
         self.models = set()
 
 
@@ -114,7 +113,7 @@ class _Registry:
         self._modules = {}  # ModuleEntry by python_name
         self._models = {}  # {'action name': MenuEntry} by model class
         for a in Application.objects.filter(enabled=True):
-            m = ModuleEntry(a.python_name, a.name, a.url)
+            m = ModuleEntry(a.python_name, a.name)
             self._modules[a.python_name] = m
 
     def register_action(self, action, entry, **kwargs):
@@ -138,17 +137,17 @@ class _Registry:
         module_entry = registry._modules[module_name]
         module_entry.models.add(model)
 
-        if not entry.name:
-            entry.name = _model_name(model)
+        if not entry.url_name:
+            entry.url_name = _model_name(model)
         entry.action = action
-        entry_url = module_entry.menu_name + '_' + entry.name + '_' + action.name
+        entry_url = module_entry.menu_name + '_' + entry.url_name + '_' + action.name
         entry.url = entry_url
         model_actions = self._models.get(model, {})
         if model_actions.has_key(action.name):
             raise Exception("Action " + action.name + " already registered for model " + str(model))
         model_actions[action.name] = entry
         self._models[model] = model_actions
-        return url(r'^/%s/%s/%s$' % (entry.name, action.name, action.url_parameters),
+        return url(r'^%s/%s/%s$' % (entry.url_name, action.name, action.url_parameters),
                    action.view_factory(model=entry.model, **kwargs), name=entry_url)
 
 

+ 2 - 2
src/rapid/templates/rapid/bare/create.html

@@ -1,6 +1,6 @@
-<p>{{object_data.model_name.title}}</p>
+<h2>{{object_data.model_name.title}}</h2>
 
-<form method="POST" action="">
+<form method="POST" action="" enctype="multipart/form-data">
     {% csrf_token %}
     {{ form.as_p }}
     <p><a class="btn btn-default rapid-submit-form">Adicionar</a></p>

+ 1 - 1
src/rapid/templates/rapid/bare/detail.html

@@ -1,5 +1,5 @@
 <span class="must_reload"></span>
-<p>{{object_data.model_name.title}}</p>
+<h2>{{object_data.model_name.title}}</h2>
 
 <div>
     {% for f, v, iter in object_data.fields_and_values %}

+ 1 - 1
src/rapid/templates/rapid/bare/list.html

@@ -16,7 +16,7 @@
         margin-right: 1em;
     }
 </style>
-<p>{{model.model_name_plural.title}}</p>
+<h2>{{model.model_name_plural.title}}</h2>
 {% load rapid_filters %}
 {% model_filters model %}
 <table class="object_list table table-striped">

+ 4 - 25
src/rapid/templates/rapid/bare/select.html

@@ -30,10 +30,10 @@
         box-shadow: 0pt 0pt 3pt 5pt #00ff00;
     }
 </style>
-<p>{{model.model_name_plural.capitalize}}</p>
+<h2>{{model.model_name_plural.capitalize}}</h2>
 {% load rapid_filters %}
 {% model_filters model %}
-<table class="object_list rapid-object-selector table table-striped">
+<table class="object_list rapid-object-selector table table-striped table-condensed">
     <thead><tr class="selectable-head">
         <td class="selectable-check"><!-- Espaço para um check -->&nbsp;</td>
         {% for f in view.fields %}
@@ -62,29 +62,8 @@
     {% endfor %}
 </table>
 <p><a class="overlay-commit btn btn-default">Adicionar na seleção</a></p>
-<p class="pagination">
-    Página:
-    {% for n,l in pages.start %}
-        <a href="l">{{n}}</a>
-    {% endfor %}
-    {% if pages.separate_start %}
-    .....
-    {% endif %}
-    {% for n,l in pages.before %}
-        <a href="l">{{n}}</a>
-    {% endfor %}
-    {{pages.page}}
-    {% for n,l in pages.after %}
-        <a href="l">{{n}}</a>
-    {% endfor %}
-    {% if pages.separate_end %}
-    .....
-    {% endif %}
-    {% for n,l in pages.end %}
-        <a href="l">{{n}}</a>
-    {% endfor %}
-</p>
- <script>
+{% pagination %}
+<script>
      $(document).ready(function(){
         $("tr.selectable-row").click(function(){
             $(this).toggleClass("selected");

+ 2 - 2
src/rapid/templates/rapid/bare/update.html

@@ -1,6 +1,6 @@
-<p>{{object_data.model_name.title}}</p>
+<h2>{{object_data.model_name.title}}</h2>
 
-<form method="POST" action="">
+<form method="POST" action=""  enctype="multipart/form-data">
     {% csrf_token %}
     {{ form.as_p }}
     {% for field, v, iter in object_data.related_fields_and_values %}

+ 4 - 4
src/rapid/templates/rapid/list/pagination.html

@@ -1,22 +1,22 @@
 <p class="pagination">
     Página:
     {% for n,l in pages.start %}
-        <a href="l" class="same-overlay">{{n}}</a>
+        <a href="{{ l }}" class="same-overlay">{{n}}</a>
     {% endfor %}
     {% if pages.separate_start %}
     .....
     {% endif %}
     {% for n,l in pages.before %}
-        <a href="l" class="same-overlay">{{n}}</a>
+        <a href="{{ l }}" class="same-overlay">{{n}}</a>
     {% endfor %}
     {{pages.page}}
     {% for n,l in pages.after %}
-        <a href="l" class="same-overlay">{{n}}</a>
+        <a href="{{ l }}" class="same-overlay">{{n}}</a>
     {% endfor %}
     {% if pages.separate_end %}
     .....
     {% endif %}
     {% for n,l in pages.end %}
-        <a href="l" class="same-overlay">{{n}}</a>
+        <a href="{{ l }}" class="same-overlay">{{n}}</a>
     {% endfor %}
 </p>

+ 3 - 3
src/rapid/templatetags/rapid_menu.py

@@ -11,12 +11,12 @@ register = template.Library()
 def _app_menu(app, request):
     models = list(app.models)
     models.sort(key=lambda m: ModelData(m).model_name(), cmp=locale.strcoll)
-    sub = '<li class="menu-group"><span>%s</span><ul class="submenu">\n' % escape(app.menu_name.capitalize())
+    sub = '<li class="menu-group"><div>%s</div><ul class="submenu">\n' % escape(app.menu_name.capitalize())
     has_model = False
     for m in models:
         st = registry.model_entry(m).get('list')
         if st:
-            read = st.permission_set.model(request)
+            read = st.permission.model(request)
             if read:
                 has_model = True
                 cd = ModelData(st.model)
@@ -54,7 +54,7 @@ def menu(request):
     <script>
         $(document).ready(function(){
             $("nav li.menu-group").addClass("collapsed");
-            $("nav li.menu-group > span").click(function(){$(this).parent().toggleClass("collapsed")});
+            $("nav li.menu-group > div").click(function(){$(this).parent().toggleClass("collapsed")});
         });
     </script>
     </nav>

+ 9 - 8
src/rapid/urls.py

@@ -2,31 +2,32 @@
 
 __author__ = 'marcos.medeiros'
 
-from django.conf.urls import include, url
 from django.contrib.auth.models import User
 
 from rapid.registry import Action
 from rapid.models import Application, Profile
 from rapid.forms import ManageUsers
 
-from rapid import views
+from rapid import register
 from rapid import permissions
 
 def _can_manage_users(request):
     if not request.user.is_authenticated:
         return []
-    return request.user.application.managed_applications.profile_set
+    p = []
+    for a in request.user.managed_applications.all():
+        p.extend(a.profile_set.all())
+    return p
 
 _manage_users_permistion = permissions.Permission(
     lambda r: False,
     _can_manage_users
 )
 
-urlpatterns = views.register_model(Application, 'aplicacao',
-                             write_set=permissions.to_superusers(), read_set=permissions.to_all()) +\
-    views.register_model(Profile, write_set=permissions.to_superusers(), read_set=permissions.to_staff()) +\
-    views.register_instance_form(Profile, 'manage_users', u'Gerenciar Usuários',
+urlpatterns = register.model(Application, write_set=permissions.to_superusers(), read_set=permissions.to_all()) +\
+    register.model(Profile, write_set=permissions.to_superusers(), read_set=permissions.to_staff()) +\
+    register.instance_form(Profile, 'manage_users', u'Gerenciar Usuários',
                             ManageUsers, _manage_users_permistion, "fa-users",
                             Action.Visibility.list) +\
-    views.register_simple_select(User, ['username'], permissions.to_staff(), 'usuario')
+    register.select(User, ['username'], permissions.to_staff(), 'usuario')
 

+ 16 - 60
src/rapid/views.py

@@ -42,8 +42,8 @@ class ListView(generic.list.ListView):
     template_name = 'rapid/bare/list.html'
     action_name = ''
     registers_per_page = 50
-    number_of_edge_pages = 3
-    number_of_middle_pages = 3
+    number_of_edge_pages = 5
+    number_of_middle_pages = 5
     fields = None
 
     class Pagination:
@@ -66,7 +66,7 @@ class ListView(generic.list.ListView):
             Números das páginas que serão listadas no começo da paginação.
             """
             e = self.number_of_edge_pages
-            for i in range(1, min(e, self.page - 1)):
+            for i in range(1, min(e+1, self.page)):
                 yield i
 
         def start(self):
@@ -80,7 +80,7 @@ class ListView(generic.list.ListView):
             Números das páginas que serão listadas na paginação antes da atual.
             """
             m = self.number_of_middle_pages
-            for i in range(max(self.page - m, m), self.page - 1):
+            for i in range(max(self.page - m, m), self.page):
                 yield i
 
         def before(self):
@@ -95,7 +95,7 @@ class ListView(generic.list.ListView):
             """
             m = self.number_of_middle_pages
             e = self.number_of_edge_pages
-            for i in range(self.page + 1, min(self.page + m, self.total_pages - e)):
+            for i in range(self.page + 1, min(self.page + m + 1, self.total_pages - e + 1)):
                 yield i
 
         def after(self):
@@ -109,7 +109,7 @@ class ListView(generic.list.ListView):
             Números das páginas que serão listadas no final da paginação.
             """
             e = self.number_of_edge_pages
-            for i in range(max(self.page + 1, self.total_pages - e), self.total_pages):
+            for i in range(max(self.page + 1, self.total_pages - e + 1), self.total_pages + 1):
                 yield i
 
         def end(self):
@@ -131,7 +131,7 @@ class ListView(generic.list.ListView):
             return self.page > self.number_of_edge_pages + self.number_of_middle_pages
 
         def get_page(self, queryset):
-            return queryset[self.registers_per_page*self.page:self.registers_per_page*(self.page+1)-1]
+            return queryset[self.registers_per_page*(self.page-1):self.registers_per_page*self.page]
 
     class View:
         order_param = 'order'
@@ -149,6 +149,9 @@ class ListView(generic.list.ListView):
                 q = q.filter(**self.filters.query_dict())
                 self.queryset = q
 
+            total = q.count()
+            pagination.total_pages = int(math.ceil(total / pagination.registers_per_page))
+
             order = request.GET.get(self.order_param)
             if order:
                 q = q.order_by(order)
@@ -199,7 +202,7 @@ class ListView(generic.list.ListView):
         # da listagem nos SA.
         context = RequestContext(request).flatten()
         context.update(kwargs)
-        total_pages = int(math.ceil(object_list.count() / self.registers_per_page)) + 1
+        total_pages = int(math.ceil(object_list.count() / self.registers_per_page))
         page = int(request.GET.get('page', 1))
         p = self.Pagination(request, page, self.number_of_edge_pages,
                                       self.number_of_middle_pages, self.registers_per_page,
@@ -268,7 +271,7 @@ def _get_form(request, model):
     for f in ModelData(model).local_fields():
         if f.is_relation() and unicode(f.bare_name()) not in default_relations_fields:
             ask_relations.append(f)
-    widgets += [(f.bare_name(), RapidSelector(f)) for f in ask_relations if f.related_model().is_controlled()]
+    widgets += [(f.bare_name(), RapidSelector(f)) for f in ask_relations if f.related_model().has_permission(request, 'select')]
     #ModelForm.Meta tem atributos com esses mesmos nomes,
     #então eu tenho que renomear.
     form_model = model
@@ -314,7 +317,7 @@ class CreateView(generic.edit.CreateView):
         parent_fields = self.fields
 
         if request.POST:
-            context['form'] = self.request_form(request)(request.POST)
+            context['form'] = self.request_form(request)(request.POST, request.FILEs)
         else:
             context['form'] = self.request_form(request)()
 
@@ -325,7 +328,7 @@ class CreateView(generic.edit.CreateView):
     def post(self, request, **kwargs):
         m = ModelData(self.model, request=request)
         if m.has_permission(request, self.action_name):
-            f = self.request_form(request)(request.POST)
+            f = self.request_form(request)(request.POST, request.FILES)
             if f.is_valid():
                 f.save()
                 return redirect(m.list_url())
@@ -359,7 +362,7 @@ class UpdateView(generic.edit.UpdateView):
         context['object_data'] = cd
 
         if request.POST:
-            context['form'] = self.request_form(request)(request.POST, instance=obj)
+            context['form'] = self.request_form(request)(request.POST, request.FILES, instance=obj)
         else:
             context['form'] = self.request_form(request)(instance=obj)
 
@@ -371,7 +374,7 @@ class UpdateView(generic.edit.UpdateView):
         obj = self.get_object()
         m = InstanceData(obj, request=request)
         if m.has_permission(request, self.action_name):
-            f = self.request_form(request)(request.POST, instance=obj)
+            f = self.request_form(request)(request.POST, request.FILES, instance=obj)
             if f.is_valid():
                 if f.instance.pk != obj.pk:
                     raise PermissionDenied
@@ -440,56 +443,9 @@ def bare_or_main(view):
         return resp
     return vw
 
-def _rvw(view_class, action_name):
-    view_class.action_name = action_name
-
-    def vw(model):
-        return bare_or_main(view_class.as_view(model=model))
-    return vw
-
-default_actions = [
-    (False, Action("list", "", [], _rvw(ListView, 'list'), "listar", "fa-list")),
-    (False, Action("view", "(?P<pk>[0-9]+)", ['pk'], _rvw(ReadView, 'view'), "ver", "fa-eye")),
-    (True, Action("edit", "(?P<pk>[0-9]+)", ['pk'], _rvw(UpdateView, 'edit'), "editar", "fa-pencil")),
-    (True, Action("add", "", [], _rvw(CreateView, 'add'), "adicionar", "fa-plus")),
-    (False, Action("select", "", [], _rvw(SelectView, 'select'), "selecionar", "fa-hand-o-up",
-                   visibility=Action.Visibility.hidden)),
-]
-
-def register_model(model, name=None, read_set=None, write_set=None, can_erase=False):
-    if not read_set:
-        read_set = permissions.default_read(model)
-    if not write_set:
-        write_set = permissions.default_write(model)
-    ret = []
-    for edt, a in default_actions:
-        if edt:
-            ret.append(registry.register_action(a, MenuEntry(model, write_set, name=name)))
-        else:
-            ret.append(registry.register_action(a, MenuEntry(model, read_set, name=name)))
-    if can_erase:
-        a =  Action("delete", "(?P<pk>[0-9]+)", ['pk'], _rvw(DeleteView, 'delete'), "apagar", "fa-trash-o")
-        ret.append(registry.register_action(a, MenuEntry(model, write_set, name=name)))
-    return [u for u in ret if u]
-
 def update_form_class(form):
     class F(UpdateView):
         def request_form(self, request):
             return form
     return F
 
-def register_instance_form(model, action_name, menu_name, form, permission_set, icon=None, visibility=None):
-    if not icon:
-        icon = ''
-    a = Action(action_name, "(?P<pk>[0-9]+)", ['pk'], _rvw(update_form_class(form), action_name),
-               menu_name, icon, visibility)
-    u = registry.register_action(a, MenuEntry(model, permission_set))
-    return [u] if u else []
-
-def register_simple_select(model, visible_fields, permission_set, name=None):
-    class Vw(SelectView):
-        fields = visible_fields
-    a = Action("select", "", [], _rvw(Vw, 'select'), "selecionar", "fa-hand-o-up",
-               visibility=Action.Visibility.hidden)
-    u = registry.register_action(a, MenuEntry(model, permission_set, name=name))
-    return [u] if u else []

+ 9 - 4
src/rapid/wrappers.py

@@ -116,7 +116,7 @@ class InstanceData:
     def has_permission(self, request, action_name):
         m = registry.model_entry(self.model.model).get(action_name)
         if m:
-            perm = m.permission_set.instances
+            perm = m.permission.instances
             return permissions.has_instance(self.model, perm(request), self.instance)
         return False
 
@@ -179,13 +179,13 @@ class ModelData:
     def can_read(self):
         if self.can_write():
             return True
-        vw = registry.model_entry(self.model)['view'].permission_set(self.request)
+        vw = registry.model_entry(self.model)['view'].permission(self.request)
         if vw:
             return vw.exists()
         return False
 
     def can_write(self):
-        ed = registry.model_entry(self.model)['edit'].permission_set(self.request)
+        ed = registry.model_entry(self.model)['edit'].permission(self.request)
         if ed:
             return ed.exists()
         return False
@@ -211,7 +211,7 @@ class ModelData:
     def has_permission(self, request, action_name):
         m = registry.model_entry(self.model).get(action_name)
         if m:
-            return bool(m.permission_set.model(request))
+            return bool(m.permission.model(request))
         return False
 
     def field_by_name(self, field_name):
@@ -241,6 +241,8 @@ class FieldData:
         return unicode(self.field.name)
 
     def name(self):
+        if self.is_auto():
+            return ModelData(self.related_model()).model_name_plural()
         if hasattr(self.field, "verbose_name"):
             return unicode(self.field.verbose_name)
         return unicode(self.field.name)
@@ -269,6 +271,9 @@ class FieldData:
             return ModelData(self.field.to)
         return None
 
+    def is_auto(self):
+        return self.field.auto_created
+
     def is_weak(self):
         if not self.is_relation():
             return False