Browse Source

ref buscador modal de Autores c pesq param reversa

pull/739/head
LeandroRoberto 8 years ago
parent
commit
3a3e5fbea7
  1. 81
      sapl/api/forms.py
  2. 78
      sapl/api/serializers.py
  3. 22
      sapl/api/urls.py
  4. 111
      sapl/api/views.py
  5. 11
      sapl/base/forms.py
  6. 9
      sapl/comissoes/models.py
  7. 9
      sapl/materia/views.py
  8. 22
      sapl/parlamentares/models.py
  9. 9
      sapl/protocoloadm/views.py
  10. 19
      sapl/sessao/models.py
  11. 3
      sapl/settings.py
  12. 31
      sapl/static/js/app.js
  13. 6
      sapl/static/styles/app.scss
  14. 17
      sapl/templates/base/autor_form.html
  15. 2
      sapl/urls.py

81
sapl/api/forms.py

@ -0,0 +1,81 @@
from django.contrib.contenttypes.fields import GenericRel
from django.db.models import Q
from django_filters.filters import MethodFilter, ModelChoiceFilter
from rest_framework.filters import FilterSet
from sapl.base.models import Autor, TipoAutor
from sapl.utils import SaplGenericRelation
def autores_models_generic_relations():
models_of_generic_relations = list(map(
lambda x: x.related_model,
filter(
lambda obj: obj.is_relation and
hasattr(obj, 'field') and
isinstance(obj, GenericRel),
Autor._meta.get_fields(include_hidden=True))
))
models = list(map(
lambda x: (x,
list(filter(
lambda field: (
isinstance(
field, SaplGenericRelation) and
field.related_model == Autor),
x._meta.get_fields(include_hidden=True)))),
models_of_generic_relations
))
return models
class AutorChoiceFilterSet(FilterSet):
q = MethodFilter()
tipo = ModelChoiceFilter(queryset=TipoAutor.objects.all())
class Meta:
model = Autor
fields = ['q',
'tipo',
'nome', ]
def filter_q(self, queryset, value):
query = value.split(' ')
if query:
q = Q()
for qtext in query:
if not qtext:
continue
q_fs = Q(nome__icontains=qtext)
order_by = []
for gr in autores_models_generic_relations():
model = gr[0]
sgr = gr[1]
for item in sgr:
if item.related_model != Autor:
continue
flag_order_by = True
for field in item.fields_search:
if flag_order_by:
flag_order_by = False
order_by.append('%s__%s' % (
item.related_query_name(),
field[0])
)
q_fs = q_fs | Q(**{'%s__%s%s' % (
item.related_query_name(),
field[0],
field[1]): qtext})
q = q & q_fs
if q:
queryset = queryset.filter(q).order_by(*order_by)
return queryset

78
sapl/api/serializers.py

@ -1,9 +1,79 @@
from django.contrib.contenttypes.fields import GenericRel
from rest_framework import serializers from rest_framework import serializers
from sapl.base.models import Autor
from sapl.utils import SaplGenericRelation
class ChoiceSerializer(serializers.Serializer): class ChoiceSerializer(serializers.Serializer):
pk = serializers.IntegerField() value = serializers.SerializerMethodField()
display = serializers.SerializerMethodField() text = serializers.SerializerMethodField()
def get_text(self, obj):
return obj[1]
def get_value(self, obj):
return obj[0]
class AutorChoiceSerializer(ChoiceSerializer):
def get_text(self, obj):
return obj.nome
def get_value(self, obj):
return obj.id
class Meta:
model = Autor
fields = ['id', 'tipo', 'nome', 'object_id', 'autor_related', 'user']
# Models que apontaram uma GenericRelation com Autor
def autores_models_generic_relations():
models_of_generic_relations = list(map(
lambda x: x.related_model,
filter(
lambda obj: obj.is_relation and
hasattr(obj, 'field') and
isinstance(obj, GenericRel),
Autor._meta.get_fields(include_hidden=True))
))
models = list(map(
lambda x: (x,
list(filter(
lambda field: (
isinstance(
field, SaplGenericRelation) and
field.related_model == Autor),
x._meta.get_fields(include_hidden=True)))),
models_of_generic_relations
))
return models
class AutorObjectRelatedField(serializers.RelatedField):
def to_representation(self, value):
return str(value)
for gr in autores_models_generic_relations():
if isinstance(value, gr[0]):
verbose_name = gr[0]._meta.verbose_name
fields_search = gr[1][0].fields_search
raise Exception(_('Erro na seleção de autor'))
class AutorSerializer(serializers.ModelSerializer):
autor_related = AutorObjectRelatedField(read_only=True)
def get_display(self, obj): class Meta:
return str(obj) model = Autor
fields = ['id', 'tipo', 'nome', 'object_id', 'autor_related', 'user']

22
sapl/api/urls.py

@ -1,18 +1,24 @@
from django.conf.urls import url from django.conf.urls import url, include
from sapl.api.views import AutorListView
from sapl.api.views import TipoAutorContentOfModelContentTypeView
from .apps import AppConfig from .apps import AppConfig
app_name = AppConfig.name app_name = AppConfig.name
# router = DefaultRouter() # router = DefaultRouter()
urlpatterns = [ # urlpatterns += router.urls
url(r'^autor/possiveis-pelo-tipo/(?P<pk>[0-9]+)$',
TipoAutorContentOfModelContentTypeView.as_view(),
name='autores_possiveis_pelo_tipo'), urlpatterns_api = [
# url(r'^$', api_root),
url(r'^autor',
AutorListView.as_view(),
name='autor_list'),
] ]
# urlpatterns += router.urls urlpatterns = [
url(r'^api/', include(urlpatterns_api))
]

111
sapl/api/views.py

@ -1,50 +1,109 @@
from django.db.models import Q from django.db.models import Q
from django.http import Http404 from django.http import Http404
from rest_framework.generics import ListAPIView, get_object_or_404 from rest_framework.filters import DjangoFilterBackend
from rest_framework.generics import ListAPIView
from rest_framework.permissions import IsAuthenticated from rest_framework.permissions import IsAuthenticated
from rest_framework.viewsets import ModelViewSet
from sapl.api.serializers import ChoiceSerializer from sapl.api.forms import AutorChoiceFilterSet
from sapl.api.serializers import ChoiceSerializer, AutorSerializer,\
AutorChoiceSerializer
from sapl.base.models import Autor, TipoAutor from sapl.base.models import Autor, TipoAutor
from sapl.utils import SaplGenericRelation from sapl.utils import SaplGenericRelation
class TipoAutorContentOfModelContentTypeView(ListAPIView): class AutorListView(ListAPIView):
serializer_class = ChoiceSerializer """
Listagem de Autores com filtro para autores cadastrados
e/ou possíveis autores.
- tipo - chave primária do Tipo de Autor a ser filtrado
- provaveis - variável sem relevância de valor, porém, sua presença
faz com que a AutorListView
mostre a lista de provaveis Autores armazenados segundo o
ContentType associado ao Tipo de Autor via relacionamento
genérico.
- q - busca textual no nome do Autor ou em fields_search
declarados no field SaplGenericRelation das GenericFks
A busca textual acontece via django-filter se não
estiver presente a variável `provaveis`. Em caso
contrário, o django-filter é desativado e a busca é feita
no model do ContentType associado ao tipo.
"""
# FIXME aplicar permissão correta de usuário # FIXME aplicar permissão correta de usuário
permission_classes = (IsAuthenticated,) permission_classes = (IsAuthenticated,)
queryset = TipoAutor.objects.all() serializer_class = AutorSerializer
model = TipoAutor queryset = Autor.objects.all()
model = Autor
def get(self, request, *args, **kwargs):
"""
desativa o django-filter se a busca for por provaveis autores
"""
provaveis = 'provaveis' in request.GET
self.filter_class = None if provaveis else AutorChoiceFilterSet
self.filter_backends = [] if provaveis else [DjangoFilterBackend]
self.serializer_class = ChoiceSerializer\
if provaveis else AutorChoiceSerializer
return ListAPIView.get(self, request, *args, **kwargs)
def get_queryset(self): def get_queryset(self):
queryset = ModelViewSet.get_queryset(self) queryset = ListAPIView.get_queryset(self)
if not self.kwargs['pk']: if self.filter_backends:
raise Http404() return queryset
params = {'content_type__isnull': False}
tipo = ''
try:
tipo = int(self.request.GET.get('tipo', ''))
if tipo:
params['id'] = tipo
except:
pass
obj = get_object_or_404(queryset, pk=self.kwargs['pk']) tipos = TipoAutor.objects.filter(**params)
if not obj.content_type: if not tipos.exists() and tipo:
raise Http404() raise Http404()
q = self.request.GET.get('q', '').strip() r = []
for tipo in tipos:
q = self.request.GET.get('q', '').strip()
model_class = obj.content_type.model_class() model_class = tipo.content_type.model_class()
fields = list(filter( fields = list(filter(
lambda field: isinstance(field, SaplGenericRelation) and lambda field: isinstance(field, SaplGenericRelation) and
field.related_model == Autor, field.related_model == Autor,
model_class._meta.get_fields(include_hidden=True))) model_class._meta.get_fields(include_hidden=True)))
assert len(fields) == 1 # retirar assert
assert len(fields) == 1
fields_search = fields[0].fields_search qs = model_class.objects.all().order_by(
fields[0].fields_search[0][0])
if q:
q_filter = Q() q_filter = Q()
for fs in fields_search: if q:
q_filter |= Q(**{'%s__icontains' % fs: q}) for item in fields:
if item.related_model != Autor:
continue
q_fs = Q()
for field in item.fields_search:
q_fs = q_fs | Q(**{'%s%s' % (
field[0],
field[1]): q})
q_filter = q_filter & q_fs
qs = qs.filter(q_filter).distinct(
fields[0].fields_search[0][0])
qs = qs.values_list('id', fields[0].fields_search[0][0])
return model_class.objects.filter(q_filter) r += list(qs)
else: r.sort(key=lambda x: x[1])
return model_class.objects.all() return r

11
sapl/base/forms.py

@ -228,9 +228,6 @@ class AutorForm(ModelForm):
User = get_user_model() User = get_user_model()
cd = self.cleaned_data cd = self.cleaned_data
if 'username' not in cd or not cd['username']:
raise ValidationError(_('O username deve ser informado.'))
if 'action_user' not in cd or not cd['action_user']: if 'action_user' not in cd or not cd['action_user']:
raise ValidationError(_('Informe se o Autor terá usuário ' raise ValidationError(_('Informe se o Autor terá usuário '
'vinculado para acesso ao Sistema.')) 'vinculado para acesso ao Sistema.'))
@ -292,6 +289,10 @@ class AutorForm(ModelForm):
'"Criar novo Usuário".') % cd['username']) '"Criar novo Usuário".') % cd['username'])
if cd['action_user'] != 'N': if cd['action_user'] != 'N':
if 'username' not in cd or not cd['username']:
raise ValidationError(_('O username deve ser informado.'))
if qs_autor.filter(user__username=cd['username']).exists(): if qs_autor.filter(user__username=cd['username']).exists():
raise ValidationError( raise ValidationError(
_('Já existe um Autor para este usuário.')) _('Já existe um Autor para este usuário.'))
@ -333,7 +334,6 @@ class AutorForm(ModelForm):
@transaction.atomic @transaction.atomic
def save(self, commit=False): def save(self, commit=False):
print('aqui')
autor = super(AutorForm, self).save(commit) autor = super(AutorForm, self).save(commit)
user_old = autor.user if autor.user_id else None user_old = autor.user if autor.user_id else None
@ -349,6 +349,7 @@ class AutorForm(ModelForm):
u.set_password(self.cleaned_data['senha']) u.set_password(self.cleaned_data['senha'])
# Define usuário como ativo em ambiente de desenvolvimento # Define usuário como ativo em ambiente de desenvolvimento
# pode logar sem a necessidade de passar pela validação de email # pode logar sem a necessidade de passar pela validação de email
# troque par False para testar o envio de email em desenvolvimento
u.is_active = settings.DEBUG u.is_active = settings.DEBUG
u.save() u.save()
autor.user = u autor.user = u
@ -384,7 +385,7 @@ class AutorForm(ModelForm):
elif self.cleaned_data['status_user'] == 'R': elif self.cleaned_data['status_user'] == 'R':
user_old.groups.remove(grupo) user_old.groups.remove(grupo)
else: elif user_old:
user_old.groups.remove(grupo) user_old.groups.remove(grupo)
return autor return autor

9
sapl/comissoes/models.py

@ -80,14 +80,19 @@ class Comissao(models.Model):
choices=YES_NO_CHOICES, choices=YES_NO_CHOICES,
verbose_name=_('Comissão Ativa?')) verbose_name=_('Comissão Ativa?'))
autor = SaplGenericRelation(Autor, fields_search=('nome', 'sigla')) autor = SaplGenericRelation(Autor,
related_query_name='comissao_set',
fields_search=(
('nome', '__icontains'),
('sigla', '__icontains')
))
class Meta: class Meta:
verbose_name = _('Comissão') verbose_name = _('Comissão')
verbose_name_plural = _('Comissões') verbose_name_plural = _('Comissões')
def __str__(self): def __str__(self):
return self.nome return self.sigla + ' - ' + self.nome
class Periodo(models.Model): # PeriodoCompComissao class Periodo(models.Model): # PeriodoCompComissao

9
sapl/materia/views.py

@ -33,13 +33,10 @@ from sapl.materia.forms import AnexadaForm, LegislacaoCitadaForm
from sapl.norma.models import LegislacaoCitada from sapl.norma.models import LegislacaoCitada
from sapl.utils import (TURNO_TRAMITACAO_CHOICES, YES_NO_CHOICES, autor_label, from sapl.utils import (TURNO_TRAMITACAO_CHOICES, YES_NO_CHOICES, autor_label,
autor_modal, gerar_hash_arquivo, get_base_url, autor_modal, gerar_hash_arquivo, get_base_url,
<<<<<<< 3276eb12726b741df770d5a6ed2a9a1a83c15849
permissoes_autor, permissoes_materia, permissoes_autor, permissoes_materia,
permissoes_protocoloadm, permission_required_for_app) permissoes_protocoloadm, permission_required_for_app,
======= montar_row_autor)
montar_row_autor, permissoes_autor, permissoes_materia,
permissoes_protocoloadm)
>>>>>>> Conc refatoração no Cada de Autor e Tipos de Autor
from .forms import (AcessorioEmLoteFilterSet, AcompanhamentoMateriaForm, from .forms import (AcessorioEmLoteFilterSet, AcompanhamentoMateriaForm,
ConfirmarProposicaoForm, DocumentoAcessorioForm, ConfirmarProposicaoForm, DocumentoAcessorioForm,

22
sapl/parlamentares/models.py

@ -265,8 +265,15 @@ class Parlamentar(models.Model):
# campo conceitual de reversão genérica para o model Autor que dá a # campo conceitual de reversão genérica para o model Autor que dá a
# o meio possível de localização de tipos de autores. # o meio possível de localização de tipos de autores.
autor = SaplGenericRelation(Autor, fields_search=('nome_completo', autor = SaplGenericRelation(
'nome_parlamentar')) Autor,
related_query_name='parlamentar_set',
fields_search=(
# na primeira posição dever ser campo simples sem __
('nome_completo', '__icontains'),
('nome_parlamentar', '__icontains'),
('filiacao__partido__sigla', '__icontains'),
))
class Meta: class Meta:
verbose_name = _('Parlamentar') verbose_name = _('Parlamentar')
@ -455,8 +462,15 @@ class Frente(models.Model):
# campo conceitual de reversão genérica para o model Autor que dá a # campo conceitual de reversão genérica para o model Autor que dá a
# o meio possível de localização de tipos de autores. # o meio possível de localização de tipos de autores.
autor = SaplGenericRelation(Autor, fields_search=('nome', autor = SaplGenericRelation(
'descricao')) Autor,
related_query_name='frente_set',
fields_search=(
('nome', '__icontains'),
('descricao', '__icontains'),
('parlamentares__filiacao__partido__sigla', '__icontains'),
('parlamentares__filiacao__partido__nome', '__icontains'),
))
class Meta: class Meta:
verbose_name = _('Frente') verbose_name = _('Frente')

9
sapl/protocoloadm/views.py

@ -1,5 +1,5 @@
import json
from datetime import date, datetime from datetime import date, datetime
import json
from braces.views import FormValidMessageMixin from braces.views import FormValidMessageMixin
from django.contrib import messages from django.contrib import messages
@ -31,6 +31,7 @@ from .models import (Autor, DocumentoAcessorioAdministrativo,
StatusTramitacaoAdministrativo, StatusTramitacaoAdministrativo,
TipoDocumentoAdministrativo, TramitacaoAdministrativo) TipoDocumentoAdministrativo, TramitacaoAdministrativo)
TipoDocumentoAdministrativoCrud = CrudAux.build( TipoDocumentoAdministrativoCrud = CrudAux.build(
TipoDocumentoAdministrativo, '') TipoDocumentoAdministrativo, '')
@ -605,11 +606,13 @@ def pesquisa_autores(request):
if request.method == 'GET': if request.method == 'GET':
q = request.GET.get('q', '') q = request.GET.get('q', '')
autor = Autor.objects.filter( """autor = Autor.objects.filter(
Q(nome__icontains=q) | Q(nome__icontains=q) |
Q(parlamentar__nome_parlamentar__icontains=q) | Q(parlamentar__nome_parlamentar__icontains=q) |
Q(comissao__nome__icontains=q) Q(comissao__nome__icontains=q)
) )"""
autor = Autor.objects.filter(nome__icontains=q)
autores = [] autores = []

19
sapl/sessao/models.py

@ -42,8 +42,13 @@ class Bancada(models.Model):
# campo conceitual de reversão genérica para o model Autor que dá a # campo conceitual de reversão genérica para o model Autor que dá a
# o meio possível de localização de tipos de autores. # o meio possível de localização de tipos de autores.
autor = SaplGenericRelation(Autor, fields_search=('nome', autor = SaplGenericRelation(Autor, related_query_name='bancada_set',
'descricao')) fields_search=(
('nome', '__icontains'),
('descricao', '__icontains'),
('partido__sigla', '__icontains'),
('partido__nome', '__icontains'),
))
class Meta: class Meta:
verbose_name = _('Bancada') verbose_name = _('Bancada')
@ -350,8 +355,14 @@ class Bloco(models.Model):
# campo conceitual de reversão genérica para o model Autor que dá a # campo conceitual de reversão genérica para o model Autor que dá a
# o meio possível de localização de tipos de autores. # o meio possível de localização de tipos de autores.
autor = SaplGenericRelation(Autor, fields_search=('nome', autor = SaplGenericRelation(Autor,
'descricao')) related_query_name='bloco_set',
fields_search=(
('nome', '__icontains'),
('descricao', '__icontains'),
('partidos__sigla', '__icontains'),
('partidos__nome', '__icontains'),
))
class Meta: class Meta:
verbose_name = _('Bloco') verbose_name = _('Bloco')

3
sapl/settings.py

@ -93,7 +93,7 @@ MIDDLEWARE_CLASSES = (
REST_FRAMEWORK = { REST_FRAMEWORK = {
"DEFAULT_RENDERER_CLASSES": ( "DEFAULT_RENDERER_CLASSES": (
"rest_framework.renderers.JSONRenderer", "rest_framework.renderers.JSONRenderer",
# "rest_framework.renderers.BrowsableAPIRenderer", #"rest_framework.renderers.BrowsableAPIRenderer",
), ),
"DEFAULT_PARSER_CLASSES": ( "DEFAULT_PARSER_CLASSES": (
"rest_framework.parsers.JSONParser", "rest_framework.parsers.JSONParser",
@ -102,7 +102,6 @@ REST_FRAMEWORK = {
"rest_framework.permissions.IsAuthenticated", "rest_framework.permissions.IsAuthenticated",
), ),
"DEFAULT_PERMISSION_CLASSES": ( "DEFAULT_PERMISSION_CLASSES": (
# "rest_framework.permissions.IsAuthenticated",
"sapl.api.permissions.DjangoModelPermissions", "sapl.api.permissions.DjangoModelPermissions",
), ),
"DEFAULT_AUTHENTICATION_CLASSES": ( "DEFAULT_AUTHENTICATION_CLASSES": (

31
sapl/static/js/app.js

@ -90,28 +90,25 @@ function autorModal() {
$("#pesquisar").click(function() { $("#pesquisar").click(function() {
var query = $("#q").val() var query = $("#q").val()
$.get("/protocoloadm/pesquisar-autor?q="+ query, function(
data, status){
$("#div-resultado").children().remove(); $.get("/api/autor?q=" + query, function(data, status) {
$("#div-resultado").children().remove();
if (data.pagination.total_entries == 0) {
$("#selecionar").attr("hidden", "hidden");
$("#div-resultado").html(
"<span class='alert'><strong>Nenhum resultado</strong></span>");
return;
}
if (data.length == 0) { var select = $(
$("#selecionar").attr("hidden", "hidden"); '<select id="resultados" \
$("#div-resultado").html( style="min-width: 90%; max-width:90%;" size="5"/>');
"<span class='alert'><strong>Nenhum resultado</strong></span>");
return;
}
var select = $( data.models.forEach(function(item, index) {
'<select id="resultados" \ select.append($("<option>").attr('value', item.value).text(item.text));
style="min-width: 90%; max-width:90%;" size="5"/>'); });
for (i = 0; i < data.length; i++) {
id = data[i][0];
nome = data[i][1];
select.append($("<option>").attr('value',id).text(nome));
}
$("#div-resultado").append("<br/>").append(select); $("#div-resultado").append("<br/>").append(select);
$("#selecionar").removeAttr("hidden", "hidden"); $("#selecionar").removeAttr("hidden", "hidden");

6
sapl/static/styles/app.scss

@ -24,12 +24,6 @@ nav {
background-color: $link-hover-color; background-color: $link-hover-color;
} }
} }
&:first-child {
& > a {
padding-left: 0px;
padding-right: 0px;
}
}
&:nth-child(2) { &:nth-child(2) {
& > .dropdown-menu { & > .dropdown-menu {
right: auto; right: auto;

17
sapl/templates/base/autor_form.html

@ -26,19 +26,20 @@ $(document).ready(function(){
} }
var update_search = function(pk, atualizar=true) { var update_search = function(pk, atualizar=true) {
var q = $('#id_q').val(); var q = $('#id_q').val();
var url = '{% url 'sapl.api:autores_possiveis_pelo_tipo' 0 %}'
url = url.replace('0', pk); var url = '{% url 'sapl.api:autor_list'%}'
var formData = { var formData = {
'q' : q, 'q' : q,
'format' : 'json', 'tipo' : pk,
'provaveis' : ''
} }
$.get(url, formData).done(function(data) { $.get(url, formData).done(function(data) {
active('pesquisa'); active('pesquisa');
if (atualizar) { if (atualizar) {
var radios = $("#div_id_autor_related .controls").html(''); var radios = $("#div_id_autor_related .controls").html('');
data.models.forEach(function (val, index) { data.models.forEach(function (val, index) {
var html_radio = '<label class="radio"><span class="icons"><span class="first-icon"></span><span class="second-icon"></span></span><input type="radio" name="autor_related" id="id_autor_related_'+index+'" value="'+val.pk+'">'+val.display+'</label>'; var html_radio = '<label class="radio"><span class="icons"><span class="first-icon"></span><span class="second-icon"></span></span><input type="radio" name="autor_related" id="id_autor_related_'+index+'" value="'+val.value+'">'+val.text+'</label>';
radios.append(html_radio); radios.append(html_radio);
}); });
@ -66,6 +67,7 @@ $(document).ready(function(){
active('nome'); active('nome');
}); });
} }
$('#id_tipo').change(function(event) { $('#id_tipo').change(function(event) {
if (event.target.selectedIndex == 0) { if (event.target.selectedIndex == 0) {
$('#id_nome, #id_q').val(''); $('#id_nome, #id_q').val('');
@ -77,10 +79,12 @@ $(document).ready(function(){
update_search(pk, false) update_search(pk, false)
} }
}); });
$('.btn-filtrar-autor').click(function(event) { $('.btn-filtrar-autor').click(function(event) {
var pk = $('#id_tipo').val(); var pk = $('#id_tipo').val();
update_search(pk); update_search(pk);
}); });
$('input[name=action_user]').change(function(event) { $('input[name=action_user]').change(function(event) {
if (!this.checked) if (!this.checked)
return; return;
@ -115,10 +119,9 @@ $(document).ready(function(){
|| (event.target.value == 'C' && username.attr('data') != '')) || (event.target.value == 'C' && username.attr('data') != ''))
$('.radiogroup-status').removeClass('hidden'); $('.radiogroup-status').removeClass('hidden');
} }
} }
}); });
$('input[name=username]').keyup(function(event) { $('input[name=username]').keyup(function(event) {
if (!flag_create) if (!flag_create)
if (this.getAttribute('data') != '' && this.value != this.getAttribute('data')) if (this.getAttribute('data') != '' && this.value != this.getAttribute('data'))

2
sapl/urls.py

@ -52,7 +52,7 @@ urlpatterns = [
# so that base /sistema/ url doesn't capture its children # so that base /sistema/ url doesn't capture its children
url(r'', include(sapl.base.urls)), url(r'', include(sapl.base.urls)),
url(r'^api/', include(sapl.api.urls)), url(r'', include(sapl.api.urls)),
] ]

Loading…
Cancel
Save