mirror of https://github.com/interlegis/sapl.git
committed by
GitHub
58 changed files with 1963 additions and 438 deletions
@ -0,0 +1 @@ |
|||
default_app_config = 'sapl.api.apps.AppConfig' |
|||
@ -0,0 +1,8 @@ |
|||
from django import apps |
|||
from django.utils.translation import ugettext_lazy as _ |
|||
|
|||
|
|||
class AppConfig(apps.AppConfig): |
|||
name = 'sapl.api' |
|||
label = 'api' |
|||
verbose_name = _('API Rest') |
|||
@ -0,0 +1,57 @@ |
|||
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.forms import autores_models_generic_relations |
|||
from sapl.base.models import Autor, TipoAutor |
|||
from sapl.utils import SaplGenericRelation |
|||
|
|||
|
|||
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 |
|||
@ -0,0 +1,34 @@ |
|||
from django.core.paginator import EmptyPage |
|||
from django.utils.encoding import force_text |
|||
from rest_framework import pagination |
|||
from rest_framework.response import Response |
|||
|
|||
|
|||
class StandardPagination(pagination.PageNumberPagination): |
|||
page_size = 10 |
|||
page_size_query_param = 'page_size' |
|||
max_page_size = 50 |
|||
|
|||
def get_paginated_response(self, data): |
|||
try: |
|||
previous_page_number = self.page.previous_page_number() |
|||
except EmptyPage: |
|||
previous_page_number = None |
|||
|
|||
try: |
|||
next_page_number = self.page.next_page_number() |
|||
except EmptyPage: |
|||
next_page_number = None |
|||
|
|||
return Response({ |
|||
'pagination': { |
|||
'previous_page': previous_page_number, |
|||
'next_page': next_page_number, |
|||
'start_index': self.page.start_index(), |
|||
'end_index': self.page.end_index(), |
|||
'total_entries': self.page.paginator.count, |
|||
'total_pages': self.page.paginator.num_pages, |
|||
'page': self.page.number, |
|||
}, |
|||
'models': data, |
|||
}) |
|||
@ -0,0 +1,17 @@ |
|||
from rest_framework.permissions import DjangoModelPermissions |
|||
|
|||
|
|||
class DjangoModelPermissions(DjangoModelPermissions): |
|||
|
|||
perms_map = { |
|||
'GET': ['%(app_label)s.list_%(model_name)s', |
|||
'%(app_label)s.detail_%(model_name)s'], |
|||
'OPTIONS': ['%(app_label)s.list_%(model_name)s', |
|||
'%(app_label)s.detail_%(model_name)s'], |
|||
'HEAD': ['%(app_label)s.list_%(model_name)s', |
|||
'%(app_label)s.detail_%(model_name)s'], |
|||
'POST': ['%(app_label)s.list_%(model_name)s'], |
|||
'PUT': ['%(app_label)s.change_%(model_name)s'], |
|||
'PATCH': ['%(app_label)s.change_%(model_name)s'], |
|||
'DELETE': ['%(app_label)s.delete_%(model_name)s'], |
|||
} |
|||
@ -0,0 +1,43 @@ |
|||
from django.contrib.contenttypes.fields import GenericRel |
|||
from rest_framework import serializers |
|||
|
|||
from sapl.base.models import Autor |
|||
from sapl.utils import SaplGenericRelation |
|||
|
|||
|
|||
class ChoiceSerializer(serializers.Serializer): |
|||
value = 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', 'nome'] |
|||
|
|||
|
|||
class AutorObjectRelatedField(serializers.RelatedField): |
|||
|
|||
def to_representation(self, value): |
|||
return str(value) |
|||
|
|||
|
|||
class AutorSerializer(serializers.ModelSerializer): |
|||
autor_related = AutorObjectRelatedField(read_only=True) |
|||
|
|||
class Meta: |
|||
model = Autor |
|||
fields = ['id', 'tipo', 'nome', 'object_id', 'autor_related', 'user'] |
|||
@ -0,0 +1,24 @@ |
|||
from django.conf.urls import url, include |
|||
from sapl.api.views import AutorListView |
|||
|
|||
from .apps import AppConfig |
|||
|
|||
|
|||
app_name = AppConfig.name |
|||
|
|||
|
|||
# router = DefaultRouter() |
|||
|
|||
# urlpatterns += router.urls |
|||
|
|||
|
|||
urlpatterns_api = [ |
|||
# url(r'^$', api_root), |
|||
url(r'^autor', |
|||
AutorListView.as_view(), |
|||
name='autor_list'), |
|||
url(r'^docs', include('rest_framework_docs.urls')), |
|||
] |
|||
urlpatterns = [ |
|||
url(r'^api/', include(urlpatterns_api)) |
|||
] |
|||
@ -0,0 +1,168 @@ |
|||
|
|||
from django.db.models import Q |
|||
from django.http import Http404 |
|||
from django.utils.translation import ugettext_lazy as _ |
|||
from rest_framework.filters import DjangoFilterBackend |
|||
from rest_framework.generics import ListAPIView |
|||
from rest_framework.permissions import IsAuthenticated, AllowAny |
|||
|
|||
from sapl.api.forms import AutorChoiceFilterSet |
|||
from sapl.api.serializers import ChoiceSerializer, AutorSerializer,\ |
|||
AutorChoiceSerializer |
|||
from sapl.base.models import Autor, TipoAutor |
|||
from sapl.utils import SaplGenericRelation, sapl_logger |
|||
|
|||
|
|||
class AutorListView(ListAPIView): |
|||
""" |
|||
Listagem de Autores com filtro para autores já cadastrados |
|||
e/ou possíveis autores. |
|||
|
|||
- tr - tipo do resultado |
|||
Prepera Lista de Autores para 3 cenários distintos |
|||
-default = 0 |
|||
|
|||
= 1 -> para (value, text) usados geralmente |
|||
em combobox, radiobox, checkbox, etc com pesquisa básica |
|||
de Autores feita pelo django-filter |
|||
-> processo usado nas pesquisas, o mais usado. |
|||
|
|||
= 2 -> para (value, text) usados geralmente |
|||
em combobox, radiobox, checkbox, etc com pesquisa básica |
|||
de Autores mas feito para Possíveis Autores armazenados |
|||
segundo o ContentType associado ao Tipo de Autor via |
|||
relacionamento genérico. |
|||
Busca feita sem django-filter processada no get_queryset |
|||
-> processo no cadastro de autores para seleção e busca |
|||
dos possíveis autores |
|||
|
|||
= 3 -> Devolve instancias da classe Autor filtradas pelo |
|||
django-filter |
|||
|
|||
- tipo - chave primária do Tipo de Autor a ser filtrado |
|||
- 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. |
|||
|
|||
Outros campos |
|||
""" |
|||
|
|||
TR_AUTOR_CHOICE_SERIALIZER = 1 |
|||
TR_CHOICE_SERIALIZER = 2 |
|||
TR_AUTOR_SERIALIZER = 3 |
|||
|
|||
# FIXME aplicar permissão correta de usuário |
|||
permission_classes = (AllowAny,) |
|||
serializer_class = AutorSerializer |
|||
queryset = Autor.objects.all() |
|||
model = Autor |
|||
|
|||
filter_class = AutorChoiceFilterSet |
|||
filter_backends = (DjangoFilterBackend, ) |
|||
serializer_class = AutorChoiceSerializer |
|||
|
|||
@property |
|||
def tr(self): |
|||
try: |
|||
tr = int(self.request.GET.get |
|||
('tr', AutorListView.TR_AUTOR_CHOICE_SERIALIZER)) |
|||
|
|||
assert tr in ( |
|||
AutorListView.TR_AUTOR_CHOICE_SERIALIZER, |
|||
AutorListView.TR_CHOICE_SERIALIZER, |
|||
AutorListView.TR_AUTOR_SERIALIZER), sapl_logger.info( |
|||
_("Tipo do Resultado a ser fornecido não existe!")) |
|||
except: |
|||
return AutorListView.TR_AUTOR_CHOICE_SERIALIZER |
|||
else: |
|||
return tr |
|||
|
|||
def get(self, request, *args, **kwargs): |
|||
""" |
|||
desativa o django-filter se a busca for por possiveis autores |
|||
parametro tr = TR_CHOICE_SERIALIZER |
|||
""" |
|||
|
|||
if self.tr == AutorListView.TR_CHOICE_SERIALIZER: |
|||
self.filter_class = None |
|||
self.filter_backends = [] |
|||
self.serializer_class = ChoiceSerializer |
|||
|
|||
elif self.tr == AutorListView.TR_AUTOR_SERIALIZER: |
|||
self.serializer_class = AutorSerializer |
|||
self.permission_classes = (IsAuthenticated,) |
|||
|
|||
return ListAPIView.get(self, request, *args, **kwargs) |
|||
|
|||
def get_queryset(self): |
|||
queryset = ListAPIView.get_queryset(self) |
|||
|
|||
if self.filter_backends: |
|||
return queryset |
|||
|
|||
params = {'content_type__isnull': False} |
|||
|
|||
tipo = '' |
|||
try: |
|||
tipo = int(self.request.GET.get('tipo', '')) |
|||
if tipo: |
|||
params['id'] = tipo |
|||
except: |
|||
pass |
|||
|
|||
tipos = TipoAutor.objects.filter(**params) |
|||
|
|||
if not tipos.exists() and tipo: |
|||
raise Http404() |
|||
|
|||
r = [] |
|||
for tipo in tipos: |
|||
q = self.request.GET.get('q', '').strip() |
|||
|
|||
model_class = tipo.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))) |
|||
|
|||
""" |
|||
fields - é um array de SaplGenericRelation que deve possuir o |
|||
atributo fields_search. Verifique na documentação da classe |
|||
a estrutura de fields_search. |
|||
""" |
|||
|
|||
assert len(fields) >= 1, (_( |
|||
'Não foi encontrado em %(model)s um atributo do tipo ' |
|||
'SaplGenericRelation que use o model %(model_autor)s') % { |
|||
'model': model_class._meta.verbose_name, |
|||
'model_autor': Autor._meta.verbose_name}) |
|||
|
|||
qs = model_class.objects.all() |
|||
|
|||
q_filter = Q() |
|||
if 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.order_by(fields[0].fields_search[0][0]).values_list( |
|||
'id', fields[0].fields_search[0][0]) |
|||
r += list(qs) |
|||
|
|||
if tipos.count() > 1: |
|||
r.sort(key=lambda x: x[1].upper()) |
|||
return r |
|||
@ -0,0 +1,55 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Generated by Django 1.9.7 on 2016-10-09 15:22 |
|||
from __future__ import unicode_literals |
|||
|
|||
from django.conf import settings |
|||
from django.db import migrations, models |
|||
import django.db.models.deletion |
|||
|
|||
|
|||
class Migration(migrations.Migration): |
|||
|
|||
dependencies = [ |
|||
migrations.swappable_dependency(settings.AUTH_USER_MODEL), |
|||
('contenttypes', '0002_remove_content_type_name'), |
|||
('base', '0021_auto_20161006_1019'), |
|||
] |
|||
|
|||
operations = [ |
|||
migrations.CreateModel( |
|||
name='Autor', |
|||
fields=[ |
|||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
|||
('object_id', models.PositiveIntegerField(blank=True, default=None, null=True)), |
|||
('nome', models.CharField(blank=True, max_length=50, verbose_name='Autor')), |
|||
('cargo', models.CharField(blank=True, max_length=50)), |
|||
('content_type', models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.CASCADE, to='contenttypes.ContentType')), |
|||
], |
|||
options={ |
|||
'verbose_name': 'Autor', |
|||
'verbose_name_plural': 'Autores', |
|||
}, |
|||
), |
|||
migrations.CreateModel( |
|||
name='TipoAutor', |
|||
fields=[ |
|||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
|||
('descricao', models.CharField(max_length=50, verbose_name='Descrição')), |
|||
('content_type', models.OneToOneField(default=None, null=True, on_delete=django.db.models.deletion.CASCADE, to='contenttypes.ContentType', verbose_name='Modelo do Tipo de Autor')), |
|||
], |
|||
options={ |
|||
'verbose_name': 'Tipo de Autor', |
|||
'verbose_name_plural': 'Tipos de Autor', |
|||
}, |
|||
), |
|||
migrations.AddField( |
|||
model_name='autor', |
|||
name='tipo', |
|||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='base.TipoAutor', verbose_name='Tipo'), |
|||
), |
|||
migrations.AddField( |
|||
model_name='autor', |
|||
name='user', |
|||
field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL), |
|||
), |
|||
] |
|||
@ -0,0 +1,25 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Generated by Django 1.9.7 on 2016-10-09 21:52 |
|||
from __future__ import unicode_literals |
|||
|
|||
from django.db import migrations, models |
|||
import django.db.models.deletion |
|||
|
|||
|
|||
class Migration(migrations.Migration): |
|||
|
|||
dependencies = [ |
|||
('base', '0022_auto_20161009_1222'), |
|||
] |
|||
|
|||
operations = [ |
|||
migrations.AlterField( |
|||
model_name='tipoautor', |
|||
name='content_type', |
|||
field=models.OneToOneField(default=None, null=True, on_delete=django.db.models.deletion.CASCADE, to='contenttypes.ContentType', verbose_name='Modelagem no SAPL'), |
|||
), |
|||
migrations.AlterUniqueTogether( |
|||
name='autor', |
|||
unique_together=set([('content_type', 'object_id')]), |
|||
), |
|||
] |
|||
@ -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'), |
|||
), |
|||
] |
|||
@ -0,0 +1,20 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Generated by Django 1.9.7 on 2016-10-11 14:38 |
|||
from __future__ import unicode_literals |
|||
|
|||
from django.db import migrations, models |
|||
|
|||
|
|||
class Migration(migrations.Migration): |
|||
|
|||
dependencies = [ |
|||
('base', '0024_auto_20161010_1002'), |
|||
] |
|||
|
|||
operations = [ |
|||
migrations.AddField( |
|||
model_name='tipoautor', |
|||
name='cria_usuario', |
|||
field=models.BooleanField(choices=[(True, 'Sim'), (False, 'Não')], default=False, help_text='Criação de Usuários víncula e libera o acesso de Autores ao sistema. Vincular um Autor a um tipo que esta opção está marcada como "Não", o Autor não terá username associado.', verbose_name='Criação de Usuários'), |
|||
), |
|||
] |
|||
@ -0,0 +1,19 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Generated by Django 1.9.7 on 2016-10-11 18:08 |
|||
from __future__ import unicode_literals |
|||
|
|||
from django.db import migrations |
|||
|
|||
|
|||
class Migration(migrations.Migration): |
|||
|
|||
dependencies = [ |
|||
('base', '0025_tipoautor_cria_usuario'), |
|||
] |
|||
|
|||
operations = [ |
|||
migrations.RemoveField( |
|||
model_name='tipoautor', |
|||
name='cria_usuario', |
|||
), |
|||
] |
|||
@ -0,0 +1,22 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Generated by Django 1.9.7 on 2016-10-11 19:24 |
|||
from __future__ import unicode_literals |
|||
|
|||
from django.conf import settings |
|||
from django.db import migrations, models |
|||
import django.db.models.deletion |
|||
|
|||
|
|||
class Migration(migrations.Migration): |
|||
|
|||
dependencies = [ |
|||
('base', '0026_remove_tipoautor_cria_usuario'), |
|||
] |
|||
|
|||
operations = [ |
|||
migrations.AlterField( |
|||
model_name='autor', |
|||
name='user', |
|||
field=models.OneToOneField(null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL), |
|||
), |
|||
] |
|||
@ -0,0 +1,53 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Generated by Django 1.9.7 on 2016-10-09 15:22 |
|||
from __future__ import unicode_literals |
|||
|
|||
from django.db import migrations, models |
|||
import django.db.models.deletion |
|||
|
|||
|
|||
class Migration(migrations.Migration): |
|||
|
|||
dependencies = [ |
|||
('protocoloadm', '0003_auto_20161009_1222'), |
|||
('materia', '0053_auto_20161004_1854'), |
|||
] |
|||
|
|||
operations = [ |
|||
migrations.RemoveField( |
|||
model_name='autor', |
|||
name='comissao', |
|||
), |
|||
migrations.RemoveField( |
|||
model_name='autor', |
|||
name='parlamentar', |
|||
), |
|||
migrations.RemoveField( |
|||
model_name='autor', |
|||
name='partido', |
|||
), |
|||
migrations.RemoveField( |
|||
model_name='autor', |
|||
name='tipo', |
|||
), |
|||
migrations.RemoveField( |
|||
model_name='autor', |
|||
name='user', |
|||
), |
|||
migrations.AlterField( |
|||
model_name='autoria', |
|||
name='autor', |
|||
field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='base.Autor', verbose_name='Autor'), |
|||
), |
|||
migrations.AlterField( |
|||
model_name='proposicao', |
|||
name='autor', |
|||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='base.Autor'), |
|||
), |
|||
migrations.DeleteModel( |
|||
name='Autor', |
|||
), |
|||
migrations.DeleteModel( |
|||
name='TipoAutor', |
|||
), |
|||
] |
|||
@ -0,0 +1,32 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Generated by Django 1.9.7 on 2016-10-09 17:18 |
|||
from __future__ import unicode_literals |
|||
|
|||
from django.db import migrations, models |
|||
import django.db.models.deletion |
|||
|
|||
|
|||
class Migration(migrations.Migration): |
|||
|
|||
dependencies = [ |
|||
('base', '0022_auto_20161009_1222'), |
|||
('materia', '0054_auto_20161009_1222'), |
|||
] |
|||
|
|||
operations = [ |
|||
migrations.AddField( |
|||
model_name='materialegislativa', |
|||
name='autores', |
|||
field=models.ManyToManyField(through='materia.Autoria', to='base.Autor'), |
|||
), |
|||
migrations.AlterField( |
|||
model_name='autoria', |
|||
name='autor', |
|||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='base.Autor', verbose_name='Autor'), |
|||
), |
|||
migrations.AlterField( |
|||
model_name='autoria', |
|||
name='materia', |
|||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='materia.MateriaLegislativa', verbose_name='Matéria Legislativa'), |
|||
), |
|||
] |
|||
@ -0,0 +1,16 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Generated by Django 1.9.7 on 2016-10-11 19:45 |
|||
from __future__ import unicode_literals |
|||
|
|||
from django.db import migrations |
|||
|
|||
|
|||
class Migration(migrations.Migration): |
|||
|
|||
dependencies = [ |
|||
('materia', '0055_auto_20161009_1418'), |
|||
('materia', '0054_auto_20161011_0904'), |
|||
] |
|||
|
|||
operations = [ |
|||
] |
|||
@ -0,0 +1,26 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Generated by Django 1.9.7 on 2016-10-09 15:22 |
|||
from __future__ import unicode_literals |
|||
|
|||
from django.db import migrations, models |
|||
import django.db.models.deletion |
|||
|
|||
|
|||
class Migration(migrations.Migration): |
|||
|
|||
dependencies = [ |
|||
('protocoloadm', '0002_delete_tipoinstituicao'), |
|||
] |
|||
|
|||
operations = [ |
|||
migrations.AlterField( |
|||
model_name='documentoadministrativo', |
|||
name='autor', |
|||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='base.Autor'), |
|||
), |
|||
migrations.AlterField( |
|||
model_name='protocolo', |
|||
name='autor', |
|||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='base.Autor'), |
|||
), |
|||
] |
|||
@ -0,0 +1,145 @@ |
|||
{% extends "crud/form.html" %} |
|||
{% load i18n %} |
|||
{% block extra_js %} |
|||
|
|||
<script type="text/javascript"> |
|||
|
|||
$(document).ready(function(){ |
|||
var flag_create = false; |
|||
if (location.href.indexOf('create') > 0) { |
|||
$('.radiogroup-status').remove(); |
|||
flag_create = true |
|||
} |
|||
var active = function(str) { |
|||
if (str == 'nome') { |
|||
$('#id_nome, #id_q').val(''); |
|||
$('.div_nome_cargo').removeClass('hidden'); |
|||
$("#div_id_autor_related .controls").html(''); |
|||
$("[data-application='AutorSearch'], .radiogroup-autor-related").addClass('hidden'); |
|||
} |
|||
else { |
|||
$('#id_nome').val(''); |
|||
$('.div_nome_cargo').addClass('hidden'); |
|||
$("#div_id_autor_related .alert").remove(); |
|||
$("[data-application='AutorSearch'], .radiogroup-autor-related").removeClass('hidden'); |
|||
} |
|||
} |
|||
var update_search = function(pk, atualizar=true) { |
|||
var q = $('#id_q').val(); |
|||
|
|||
var url = '{% url 'sapl.api:autor_list'%}' |
|||
|
|||
var formData = { |
|||
'q' : q, |
|||
'tipo' : pk, |
|||
'tr' : '2' // tipo_resultado = 2 - api fornecerá possíveis Autores |
|||
} |
|||
$.get(url, formData).done(function(data) { |
|||
active('pesquisa'); |
|||
if (atualizar) { |
|||
var radios = $("#div_id_autor_related .controls").html(''); |
|||
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.value+'">'+val.text+'</label>'; |
|||
radios.append(html_radio); |
|||
}); |
|||
|
|||
if (data.models.length > 1) { |
|||
$('input[name=autor_related]').change(function(event){ |
|||
if (this.checked) |
|||
$('#id_q').val(event.target.parentElement.textContent); |
|||
//$('input[name=autor_related]:not(:checked)').closest('.radio').remove(); |
|||
}); |
|||
} |
|||
else { |
|||
$('input[name=autor_related]').prop('checked', 'checked'); |
|||
$('input[name=autor_related]').closest('.radio').addClass('checked'); |
|||
} |
|||
|
|||
if (data.pagination.total_entries > 10) |
|||
radios.before('<div class="alert alert-info" role="alert"><strong>{% trans "Foram encontrados" %} '+data.pagination.total_entries+' {% trans "registros"%}</strong>'+' {% trans "mas será mostrado apenas os 10 primeiros resultados. Coloque mais informações no campo pesquisa para refinar sua busca."%}</div>'); |
|||
else if (data.pagination.total_entries == 0) |
|||
radios.before('<div class="alert alert-info" role="alert"><strong>{% trans "Não foram encontrados registros com os termos de pesquisa informados." %}</div>'); |
|||
} |
|||
else{ |
|||
$('#id_nome, #id_q').val(''); |
|||
} |
|||
}).fail(function(data) { |
|||
active('nome'); |
|||
}); |
|||
} |
|||
|
|||
$('#id_tipo').change(function(event) { |
|||
if (event.target.selectedIndex == 0) { |
|||
$('#id_nome, #id_q').val(''); |
|||
active('nome'); |
|||
} |
|||
else { |
|||
var pk = this[event.target.selectedIndex].value; |
|||
$('input[name=autor_related]').closest('.radio').remove(); |
|||
update_search(pk, false) |
|||
} |
|||
}); |
|||
|
|||
$('.btn-filtrar-autor').click(function(event) { |
|||
var pk = $('#id_tipo').val(); |
|||
update_search(pk); |
|||
}); |
|||
|
|||
$('input[name=action_user]').change(function(event) { |
|||
if (!this.checked) |
|||
return; |
|||
|
|||
$('#div_id_username input').prop('readonly', ''); |
|||
|
|||
if (event.target.value == 'C') { |
|||
$('.new_user_fields, #div_id_username').removeClass('hidden'); |
|||
$('input[name=username]').val(''); |
|||
} |
|||
else if (event.target.value == 'N') { |
|||
$('.new_user_fields').addClass('hidden'); |
|||
if ($('input[name=username]').attr('data') != '') |
|||
$('.radiogroup-status').removeClass('hidden'); |
|||
|
|||
if (flag_create) { |
|||
$('#div_id_username').addClass('hidden'); |
|||
} |
|||
else { |
|||
$('#div_id_username input').prop('readonly', 'readonly'); |
|||
} |
|||
} |
|||
else { |
|||
$('.radiogroup-status').addClass('hidden'); |
|||
$('#div_id_username').removeClass('hidden'); |
|||
$('.new_user_fields').addClass('hidden'); |
|||
} |
|||
if (!flag_create) { |
|||
var username = $('input[name=username]'); |
|||
if (username.length == 1) { |
|||
if ((event.target.value == 'A' && username.attr('data') != '' && username[0].value != username.attr('data')) |
|||
|| (event.target.value == 'C' && username.attr('data') != '')) |
|||
$('.radiogroup-status').removeClass('hidden'); |
|||
} |
|||
} |
|||
}); |
|||
|
|||
$('input[name=username]').keyup(function(event) { |
|||
if (!flag_create) |
|||
if (this.getAttribute('data') != '' && this.value != this.getAttribute('data')) |
|||
$('.radiogroup-status').removeClass('hidden'); |
|||
else |
|||
$('.radiogroup-status').addClass('hidden'); |
|||
}); |
|||
|
|||
$('input[name=action_user]:checked').trigger('change'); |
|||
$('input[name=autor_related]').closest('.radio').remove(); |
|||
|
|||
var pk = $('#id_tipo').val(); |
|||
if (pk) |
|||
update_search(pk, $('#id_q').val().length > 0) |
|||
|
|||
}); |
|||
|
|||
|
|||
</script> |
|||
|
|||
{% endblock %} |
|||
@ -0,0 +1,20 @@ |
|||
{% extends "crud/form.html" %} |
|||
{% load i18n %} |
|||
{% block extra_js %} |
|||
|
|||
<script type="text/javascript"> |
|||
|
|||
$(document).ready(function(){ |
|||
|
|||
$('#id_content_type').change(function(event) { |
|||
if (event.target.selectedIndex == 0) |
|||
$('#id_descricao').val(''); |
|||
else |
|||
$('#id_descricao').val(this[event.target.selectedIndex].text); |
|||
}); |
|||
}); |
|||
|
|||
|
|||
</script> |
|||
|
|||
{% endblock %} |
|||
@ -0,0 +1,14 @@ |
|||
{% load crispy_forms_filters %} |
|||
{% load l10n %} |
|||
|
|||
<div class="controls controls-checkbox {{ field_class }}"{% if flat_attrs %} {{ flat_attrs|safe }}{% endif %}> |
|||
{% include 'bootstrap3/layout/field_errors_block.html' %} |
|||
{% for choice in field.field.choices %} |
|||
<label class="checkbox{% if field.field.inline_class %} checkbox-inline{% endif %}{% if choice.0 in field.value or choice.0|stringformat:"s" in field.value or choice.0|stringformat:"s" == field.value|stringformat:"s" %} checked{% endif %}" for="id_{{ field.html_name }}_{{ forloop.counter }}"> |
|||
<span class="icons"><span class="first-icon"></span><span class="second-icon fa fa-check"></span></span> |
|||
|
|||
<input type="checkbox"{% if choice.0 in field.value or choice.0|stringformat:"s" in field.value or choice.0|stringformat:"s" == field.value|stringformat:"s" %} checked="checked"{% endif %} name="{{ field.html_name }}" id="id_{{ field.html_name }}_{{ forloop.counter }}" value="{{ choice.0|unlocalize }}" {{ field.field.widget.attrs|flatatt }}>{{ choice.1|unlocalize }} |
|||
</label> |
|||
{% endfor %} |
|||
{% include 'bootstrap3/layout/help_text.html' %} |
|||
</div> |
|||
@ -0,0 +1,18 @@ |
|||
{% load crispy_forms_filters %} |
|||
{% load l10n %} |
|||
|
|||
<div class="controls controls-radio {{ field_class }}"{% if flat_attrs %} {{ flat_attrs|safe }}{% endif %}> |
|||
{% include 'bootstrap3/layout/field_errors_block.html' %} |
|||
{% for choice in field.field.choices %} |
|||
|
|||
<label class="radio {% if inline_class %}radio-{{ inline_class }}{% endif %}{% if choice.0 in field.value or choice.0|stringformat:"s" in field.value or choice.0|stringformat:"s" == field.value|stringformat:"s" %} checked{% endif %}" for="id_{{ field.html_name }}_{{ forloop.counter }}"> |
|||
<span class="icons"> |
|||
<span class="first-icon"></span> |
|||
<span class="second-icon"></span> |
|||
</span> |
|||
<input type="radio"{% if choice.0|stringformat:"s" == field.value|stringformat:"s" %} checked="checked"{% endif %} name="{{ field.html_name }}" id="id_{{ field.html_name }}_{{ forloop.counter }}" value="{{ choice.0|unlocalize }}" {{ field.field.widget.attrs|flatatt }}>{{ choice.1|unlocalize }} |
|||
</label> |
|||
{% endfor %} |
|||
|
|||
{% include 'bootstrap3/layout/help_text.html' %} |
|||
</div> |
|||
@ -0,0 +1,12 @@ |
|||
{% if field.is_hidden %} |
|||
{{ field }} |
|||
{% else %} |
|||
<div id="div_{{ field.auto_id }}" class="form-group{% if wrapper_class %} {{ wrapper_class }}{% endif %}{% if form_show_errors and field.errors %} has-error{% endif %}{% if field.css_classes %} {{ field.css_classes }}{% endif %}"> |
|||
{% if field.label %} |
|||
<label for="{{ field.auto_id }}" class="control-label {{ label_class }}{% if field.field.required %} requiredField{% endif %}"> |
|||
{{ field.label|safe }}{% if field.field.required %}<span class="asteriskField">*</span>{% endif %} |
|||
</label> |
|||
{% endif %} |
|||
{% include 'bootstrap3/layout/radioselect.html' %} |
|||
</div> |
|||
{% endif %} |
|||
Loading…
Reference in new issue