Sistema de Apoio ao Processo Legislativo
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

228 lines
6.4 KiB

"""
This file is part of SAPL.
Copyright (C) 2016 Interlegis
"""
from braces.views import FormMessagesMixin
from django.conf.urls import url
from django.core.urlresolvers import reverse
from django.utils.translation import ugettext_lazy as _
from django.views.generic import (CreateView, DeleteView, DetailView, ListView,
UpdateView)
from crispy_layout_mixin import CrispyLayoutFormMixin, get_field_display
def from_to(start, end):
return list(range(start, end + 1))
def make_pagination(index, num_pages):
'''Make a list of adjacent page ranges interspersed with "None"s
The list starts with [1, 2] and end with [num_pages-1, num_pages].
The list includes [index-1, index, index+1]
"None"s separate those ranges and mean ellipsis (...)
Example: [1, 2, None, 10, 11, 12, None, 29, 30]
'''
PAGINATION_LENGTH = 10
if num_pages <= PAGINATION_LENGTH:
return from_to(1, num_pages)
else:
if index - 1 <= 5:
tail = [num_pages - 1, num_pages]
head = from_to(1, PAGINATION_LENGTH - 3)
else:
if index + 1 >= num_pages - 3:
tail = from_to(index - 1, num_pages)
else:
tail = [index - 1, index, index + 1,
None, num_pages - 1, num_pages]
head = from_to(1, PAGINATION_LENGTH - len(tail) - 1)
return head + [None] + tail
class BaseCrudMixin(CrispyLayoutFormMixin):
@property
def namespace(self):
return self.model._meta.model_name
def resolve_url(self, url_name, args=None):
return reverse('%s:%s' % (self.namespace, url_name), args=args)
@property
def list_url(self):
return self.resolve_url('list')
@property
def create_url(self):
return self.resolve_url('create')
@property
def detail_url(self):
return self.resolve_url('detail', args=(self.object.id,))
@property
def update_url(self):
return self.resolve_url('update', args=(self.object.id,))
@property
def delete_url(self):
return self.resolve_url('delete', args=(self.object.id,))
def get_template_names(self):
names = super(BaseCrudMixin, self).get_template_names()
names.append("crud/%s.html" %
self.template_name_suffix.lstrip('_'))
return names
@property
def verbose_name(self):
return self.model._meta.verbose_name
@property
def verbose_name_plural(self):
return self.model._meta.verbose_name_plural
class CrudListMixin():
paginate_by = 10
no_entries_msg = _('Nenhum registro encontrado.')
@property
def title(self):
return self.verbose_name_plural
def _as_row(self, obj):
return [
(get_field_display(obj, name)[1], obj.pk if i == 0 else None)
for i, name in enumerate(self.list_field_names)]
def get_context_data(self, **kwargs):
context = super(CrudListMixin, self).get_context_data(**kwargs)
# pagination
page_obj = context['page_obj']
paginator = context['paginator']
context['page_range'] = make_pagination(
page_obj.number, paginator.num_pages)
# rows
object_list = context['object_list']
context['rows'] = [self._as_row(obj) for obj in object_list]
context['headers'] = [
self.model._meta.get_field(fieldname).verbose_name
for fieldname in self.list_field_names]
context['NO_ENTRIES_MSG'] = self.no_entries_msg
return context
def make_form_invalid_message(msg):
return '%s %s' % (_('Formulário inválido.'), msg)
class CrudCreateMixin(FormMessagesMixin):
form_valid_message = _('Registro criado com sucesso!')
form_invalid_message = make_form_invalid_message(
_('O registro não foi criado.'))
@property
def title(self):
return _('Adicionar %(verbose_name)s') % {
'verbose_name': self.verbose_name}
@property
def cancel_url(self):
return self.list_url
def get_success_url(self):
return self.detail_url
class CrudDetailMixin():
@property
def title(self):
# TODO: can we just use view.object in the templates????
return str(self.object)
class CrudUpdateMixin(FormMessagesMixin):
form_valid_message = _('Registro alterado com sucesso!')
form_invalid_message = make_form_invalid_message(
_('Suas alterações não foram salvas.'))
@property
def title(self):
return str(self.object)
@property
def cancel_url(self):
return self.detail_url
def get_success_url(self):
return self.detail_url
class CrudDeleteMixin(FormMessagesMixin):
form_valid_message = _('Registro excluído com sucesso!')
form_invalid_message = make_form_invalid_message(
_('O registro não foi excluído.'))
def get_success_url(self):
return self.list_url
class Crud(object):
def __init__(self, model, help_path,
base_mixin=BaseCrudMixin,
list_mixin=CrudListMixin,
create_mixin=CrudCreateMixin,
detail_mixin=CrudDetailMixin,
update_mixin=CrudUpdateMixin,
delete_mixin=CrudDeleteMixin):
class CrudMixin(base_mixin):
pass
CrudMixin.model = model
CrudMixin.help_path = help_path
class CrudListView(CrudMixin, list_mixin, ListView):
pass
class CrudCreateView(CrudMixin, create_mixin, CreateView):
pass
class CrudDetailView(CrudMixin, detail_mixin, DetailView):
pass
class CrudUpdateView(CrudMixin, update_mixin, UpdateView):
pass
class CrudDeleteView(CrudMixin, delete_mixin, DeleteView):
pass
self.urlpatterns = [
url(r'^$', CrudListView.as_view(), name='list'),
url(r'^create$', CrudCreateView.as_view(), name='create'),
url(r'^(?P<pk>\d+)$', CrudDetailView.as_view(), name='detail'),
url(r'^(?P<pk>\d+)/edit$',
CrudUpdateView.as_view(), name='update'),
url(r'^(?P<pk>\d+)/delete$',
CrudDeleteView.as_view(), name='delete'),
]
self.namespace = CrudMixin().namespace
self.urls = self.urlpatterns, self.namespace, self.namespace
# FIXME Refatorar código que precisa desse atributo e remover
self.CrudDetailView = CrudDetailView