diff --git a/sapl/api/views.py b/sapl/api/views.py index 08181d8a0..a8058e5c6 100644 --- a/sapl/api/views.py +++ b/sapl/api/views.py @@ -1,3 +1,4 @@ +from django.db.models import Q from django.http import Http404 from rest_framework import mixins, viewsets from rest_framework.generics import ListAPIView, GenericAPIView,\ @@ -8,6 +9,7 @@ from rest_framework.viewsets import ModelViewSet from sapl.api.serializers import ChoiceSerializer from sapl.base.models import Autor, TipoAutor +from sapl.utils import SaplGenericRelation class TipoAutorContentOfModelContentTypeView(ListAPIView): @@ -27,10 +29,24 @@ class TipoAutorContentOfModelContentTypeView(ListAPIView): if not obj.content_type: raise Http404 - q = self.request.GET.get('q', None) + q = self.request.GET.get('q', '').strip() - if not q: - return [] + model_class = obj.content_type.model_class() + + fields = list(filter( + lambda field: isinstance(field, SaplGenericRelation) and + field.related_model == Autor, + model_class._meta.get_fields(include_hidden=True))) + + assert len(fields) == 1 + + fields_search = fields[0].fields_search + + if q: + q_filter = Q() + for fs in fields_search: + q_filter |= Q(**{'%s__icontains' % fs: q}) + + return model_class.objects.filter(q_filter)[:10] else: - return obj.content_type.model_class().objects.filter( - nome__icontains=q)[:10] + return model_class.objects.all()[:10] diff --git a/sapl/base/forms.py b/sapl/base/forms.py index 93ae87290..bfc85b7b6 100644 --- a/sapl/base/forms.py +++ b/sapl/base/forms.py @@ -85,21 +85,22 @@ class AutorForm(ModelForm): q = forms.CharField( max_length=50, required=False, - label='Pesquise o nome do Autor com o tipo Selecionado') - content_object = forms.ChoiceField(label='', - required=False, - widget=forms.RadioSelect()) + label='Pesquise o nome do Autor com o ' + 'tipo Selecionado e marque o escolhido.') + autor_related = forms.ChoiceField(label='', + required=False, + widget=forms.RadioSelect()) class Meta: model = Autor fields = ['tipo', 'nome', - 'content_object', + 'autor_related', 'q'] def __init__(self, *args, **kwargs): - content_object = Div( + autor_related = Div( FieldWithButtons( Field('q', @@ -108,20 +109,16 @@ class AutorForm(ModelForm): StrictButton( _('Filtrar'), css_class='btn-default btn-filtrar-autor', type='button')), - - - - - Field('content_object'), + Field('autor_related'), css_class='hidden', data_action='create', data_application='AutorSearch', - data_field='content_object') + data_field='autor_related') row1 = to_row([ ('tipo', 4), ('nome', 8), - (content_object, 8), + (autor_related, 8), ]) @@ -130,11 +127,11 @@ class AutorForm(ModelForm): super(AutorForm, self).__init__(*args, **kwargs) - self.fields['content_object'].choices = [('1', 'teste')] - if self.instance and self.instance.content_object: - self.fields['content_object'].choices = [ - (self.instance.content_object.pk, - self.instance.content_object)] + self.fields['autor_related'].choices = [] + if self.instance and self.instance.autor_related: + self.fields['autor_related'].choices = [ + (self.instance.autor_related.pk, + self.instance.autor_related)] def valida_igualdade(self, texto1, texto2, msg): if texto1 != texto2: diff --git a/sapl/base/migrations/0024_auto_20161010_1002.py b/sapl/base/migrations/0024_auto_20161010_1002.py new file mode 100644 index 000000000..0de18cad7 --- /dev/null +++ b/sapl/base/migrations/0024_auto_20161010_1002.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.7 on 2016-10-10 13:02 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('base', '0023_auto_20161009_1852'), + ] + + operations = [ + migrations.AlterField( + model_name='autor', + name='nome', + field=models.CharField(blank=True, max_length=50, verbose_name='Nome do Autor'), + ), + migrations.AlterField( + model_name='autor', + name='tipo', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='base.TipoAutor', verbose_name='Tipo do Autor'), + ), + ] diff --git a/sapl/base/models.py b/sapl/base/models.py index 67896fef9..fecf7f3d2 100644 --- a/sapl/base/models.py +++ b/sapl/base/models.py @@ -160,7 +160,7 @@ class Autor(models.Model): blank=True, null=True, default=None) object_id = models.PositiveIntegerField( blank=True, null=True, default=None) - content_object = GenericForeignKey('content_type', 'object_id') + autor_related = GenericForeignKey('content_type', 'object_id') nome = models.CharField( max_length=50, blank=True, verbose_name=_('Nome do Autor')) @@ -174,8 +174,8 @@ class Autor(models.Model): def __str__(self): - if self.content_object: - return str(self.content_object) + if self.autor_related: + return str(self.autor_related) else: if str(self.cargo): return _('%(nome)s - %(cargo)s') % { diff --git a/sapl/comissoes/models.py b/sapl/comissoes/models.py index 9919857c1..c0c3ec4d3 100644 --- a/sapl/comissoes/models.py +++ b/sapl/comissoes/models.py @@ -6,7 +6,7 @@ from model_utils import Choices from sapl.base.models import Autor from sapl.parlamentares.models import Parlamentar -from sapl.utils import YES_NO_CHOICES +from sapl.utils import YES_NO_CHOICES, SaplGenericRelation class TipoComissao(models.Model): @@ -81,7 +81,7 @@ class Comissao(models.Model): choices=YES_NO_CHOICES, verbose_name=_('Comissão Ativa?')) - autor = GenericRelation(Autor) + autor = SaplGenericRelation(Autor, fields_search=('nome', 'sigla')) class Meta: verbose_name = _('Comissão') diff --git a/sapl/parlamentares/models.py b/sapl/parlamentares/models.py index 2629eac6c..ef7afeb7c 100644 --- a/sapl/parlamentares/models.py +++ b/sapl/parlamentares/models.py @@ -8,7 +8,7 @@ from model_utils import Choices from sapl.base.models import Autor from sapl.utils import (INDICADOR_AFASTAMENTO, UF, YES_NO_CHOICES, intervalos_tem_intersecao, - restringe_tipos_de_arquivo_img) + restringe_tipos_de_arquivo_img, SaplGenericRelation) class Legislatura(models.Model): @@ -264,7 +264,9 @@ class Parlamentar(models.Model): verbose_name=_('Fotografia'), validators=[restringe_tipos_de_arquivo_img]) - autor = GenericRelation(Autor) + # campo conceitual de reversão genérica para o model Autor + autor = SaplGenericRelation(Autor, fields_search=('nome_completo', + 'nome_parlamentar')) class Meta: verbose_name = _('Parlamentar') diff --git a/sapl/templates/base/autor_form.html b/sapl/templates/base/autor_form.html index dec8b20a3..710747cc8 100644 --- a/sapl/templates/base/autor_form.html +++ b/sapl/templates/base/autor_form.html @@ -7,10 +7,10 @@ $(document).ready(function(){ var active = function(str) { if (str == 'nome') { - $('#id_q').val(''); + $('#id_nome, #id_q').val(''); $('#div_id_nome').removeClass('hidden'); $("[data-application='AutorSearch']").addClass('hidden'); - $("#div_id_content_object .controls").html(''); + $("#div_id_autor_related .controls").html(''); } else { $('#id_nome').val(''); @@ -18,7 +18,7 @@ $(document).ready(function(){ $("[data-application='AutorSearch']").removeClass('hidden'); } } - var update_search = function(pk) { + var update_search = function(pk, atualizar=true) { var q = $('#id_q').val(); var url = '{% url 'sapl.api:autores_possiveis_pelo_tipo' 0 %}' url = url.replace('0', pk); @@ -28,15 +28,29 @@ $(document).ready(function(){ 'format' : 'json', } $.get(url, formData).done(function(data) { - var radios = $("#div_id_content_object .controls").html(''); - active('pesquisa'); - data.forEach(function (val, index) { - var html_radio = '
'; - radios.append(html_radio); + active('pesquisa'); + if (atualizar) { + var radios = $("#div_id_autor_related .controls").html(''); + data.forEach(function (val, index) { + var html_radio = '
'; + radios.append(html_radio); + }); + if (data.length > 1) { + $('input[name=autor_related]').change(function(event){ + $('#id_q').val(event.target.parentElement.textContent); + //$('input[name=autor_related]:not(:checked)').closest('.radio').remove(); + }); + } + else { + $('input[name=autor_related]').prop('checked', 'checked') + } + } + else{ + $('#id_nome, #id_q').val(''); + } + }).fail(function(data) { + active('nome'); }); - }).fail(function(data) { - active('nome'); - }); } $('#id_tipo').change(function(event) { @@ -46,7 +60,8 @@ $(document).ready(function(){ } else { var pk = this[event.target.selectedIndex].value; - update_search(pk); + $('input[name=autor_related]').closest('.radio').remove(); + update_search(pk, false) } }); $('.btn-filtrar-autor').click(function(event) { diff --git a/sapl/utils.py b/sapl/utils.py index d4e7bed3f..3b5cbd36f 100644 --- a/sapl/utils.py +++ b/sapl/utils.py @@ -10,6 +10,7 @@ from django.conf import settings from django.contrib import admin from django.contrib.auth.decorators import user_passes_test from django.contrib.auth.models import Permission +from django.contrib.contenttypes.fields import GenericRelation from django.contrib.contenttypes.models import ContentType from django.core.exceptions import PermissionDenied, ValidationError from django.utils.translation import ugettext_lazy as _ @@ -55,6 +56,15 @@ autor_modal = ''' ''' +class SaplGenericRelation(GenericRelation): + + def __init__(self, to, fields_search=(), **kwargs): + + assert fields_search + self.fields_search = fields_search + super().__init__(to, **kwargs) + + class ImageThumbnailFileInput(ClearableFileInput): template_name = 'floppyforms/image_thumbnail.html'