From aeca5f6fb6336248063602299aad1e238ab89a19 Mon Sep 17 00:00:00 2001 From: Luciano Almeida Date: Tue, 24 Jan 2017 18:16:17 -0200 Subject: [PATCH 01/11] Migra usando django-reversion Signed-off-by: Luciano Almeida --- sapl/base/models.py | 6 + sapl/comissoes/models.py | 7 + sapl/compilacao/models.py | 16 +++ sapl/legacy/migration.py | 120 +++++++++++------- sapl/lexml/models.py | 3 + .../migrations/0075_auto_20170123_1548.py | 35 +++++ sapl/materia/models.py | 23 ++++ .../migrations/0033_auto_20170123_1548.py | 20 +++ sapl/norma/models.py | 7 + sapl/painel/models.py | 3 + sapl/parlamentares/models.py | 18 +++ .../migrations/0010_auto_20170123_1548.py | 25 ++++ sapl/protocoloadm/models.py | 7 + sapl/sessao/models.py | 26 ++++ sapl/settings.py | 2 +- 15 files changed, 272 insertions(+), 46 deletions(-) create mode 100644 sapl/materia/migrations/0075_auto_20170123_1548.py create mode 100644 sapl/norma/migrations/0033_auto_20170123_1548.py create mode 100644 sapl/protocoloadm/migrations/0010_auto_20170123_1548.py diff --git a/sapl/base/models.py b/sapl/base/models.py index ab95553ba..a773f41ff 100644 --- a/sapl/base/models.py +++ b/sapl/base/models.py @@ -2,6 +2,7 @@ from django.contrib.contenttypes.fields import GenericForeignKey from django.contrib.contenttypes.models import ContentType from django.db import models from django.utils.translation import ugettext_lazy as _ +import reversion from sapl.utils import UF, YES_NO_CHOICES, get_settings_auth_user_model @@ -20,6 +21,7 @@ def get_casa_media_path(instance, filename): return get_sessao_media_path(instance, 'Logotipo', filename) +@reversion.register() class CasaLegislativa(models.Model): # TODO ajustar todos os max_length !!!! # cod_casa => id (pk) @@ -59,6 +61,7 @@ class CasaLegislativa(models.Model): 'municipio': self.municipio} +@reversion.register() class ProblemaMigracao(models.Model): content_type = models.ForeignKey(ContentType, verbose_name=_('Tipo de Content')) @@ -76,6 +79,7 @@ class ProblemaMigracao(models.Model): verbose_name_plural = _('Problemas na Migração') +@reversion.register() class AppConfig(models.Model): POLITICA_PROTOCOLO_CHOICES = ( @@ -136,6 +140,7 @@ class AppConfig(models.Model): 'id': self.id} +@reversion.register() class TipoAutor(models.Model): descricao = models.CharField(max_length=50, verbose_name=_('Descrição')) @@ -153,6 +158,7 @@ class TipoAutor(models.Model): return self.descricao +@reversion.register() class Autor(models.Model): user = models.OneToOneField(get_settings_auth_user_model(), diff --git a/sapl/comissoes/models.py b/sapl/comissoes/models.py index 441eacba6..3f0a37144 100644 --- a/sapl/comissoes/models.py +++ b/sapl/comissoes/models.py @@ -2,12 +2,14 @@ from django.db import models from django.utils.translation import ugettext_lazy as _ from model_utils import Choices +import reversion from sapl.base.models import Autor from sapl.parlamentares.models import Parlamentar from sapl.utils import YES_NO_CHOICES, SaplGenericRelation +@reversion.register() class TipoComissao(models.Model): NATUREZA_CHOICES = Choices(('T', 'temporaria', _('Temporária')), ('P', 'permanente', _('Permanente'))) @@ -28,6 +30,7 @@ class TipoComissao(models.Model): return self.nome +@reversion.register() class Comissao(models.Model): tipo = models.ForeignKey(TipoComissao, verbose_name=_('Tipo')) nome = models.CharField(max_length=60, verbose_name=_('Nome')) @@ -95,6 +98,7 @@ class Comissao(models.Model): return self.sigla + ' - ' + self.nome +@reversion.register() class Periodo(models.Model): # PeriodoCompComissao data_inicio = models.DateField(verbose_name=_('Data Início')) data_fim = models.DateField( @@ -112,6 +116,7 @@ class Periodo(models.Model): # PeriodoCompComissao return '-' +@reversion.register() class CargoComissao(models.Model): nome = models.CharField(max_length=50, verbose_name=_('Cargo')) unico = models.BooleanField( @@ -125,6 +130,7 @@ class CargoComissao(models.Model): return self.nome +@reversion.register() class Composicao(models.Model): # IGNORE comissao = models.ForeignKey(Comissao, verbose_name=_('Comissão')) periodo = models.ForeignKey(Periodo, verbose_name=_('Período')) @@ -137,6 +143,7 @@ class Composicao(models.Model): # IGNORE return '%s: %s' % (self.comissao.sigla, self.periodo) +@reversion.register() class Participacao(models.Model): # ComposicaoComissao composicao = models.ForeignKey(Composicao, related_name='participacao_set') parlamentar = models.ForeignKey(Parlamentar) diff --git a/sapl/compilacao/models.py b/sapl/compilacao/models.py index 5b022fffa..a633303ee 100644 --- a/sapl/compilacao/models.py +++ b/sapl/compilacao/models.py @@ -11,12 +11,14 @@ from django.http.response import Http404 from django.template import defaultfilters from django.utils.decorators import classonlymethod from django.utils.translation import ugettext_lazy as _ +import reversion from sapl.compilacao.utils import (get_integrations_view_names, int_to_letter, int_to_roman) from sapl.utils import YES_NO_CHOICES, get_settings_auth_user_model +@reversion.register() class TimestampedMixin(models.Model): created = models.DateTimeField( verbose_name=_('created'), @@ -28,6 +30,7 @@ class TimestampedMixin(models.Model): abstract = True +@reversion.register() class BaseModel(models.Model): class Meta: @@ -75,6 +78,7 @@ class BaseModel(models.Model): update_fields=update_fields) +@reversion.register() class PerfilEstruturalTextoArticulado(BaseModel): sigla = models.CharField( max_length=10, unique=True, verbose_name=_('Sigla')) @@ -100,6 +104,7 @@ class PerfilEstruturalTextoArticulado(BaseModel): return self.nome +@reversion.register() class TipoTextoArticulado(models.Model): sigla = models.CharField(max_length=3, verbose_name=_('Sigla')) descricao = models.CharField(max_length=50, verbose_name=_('Descrição')) @@ -161,6 +166,7 @@ PRIVACIDADE_STATUS = ( ) +@reversion.register() class TextoArticulado(TimestampedMixin): data = models.DateField(blank=True, null=True, verbose_name=_('Data')) ementa = models.TextField(verbose_name=_('Ementa')) @@ -492,6 +498,7 @@ class TextoArticulado(TimestampedMixin): update(dpk) +@reversion.register() class TipoNota(models.Model): sigla = models.CharField( max_length=10, unique=True, verbose_name=_('Sigla')) @@ -507,6 +514,7 @@ class TipoNota(models.Model): return '%s: %s' % (self.sigla, self.nome) +@reversion.register() class TipoVide(models.Model): sigla = models.CharField( max_length=10, unique=True, verbose_name=_('Sigla')) @@ -520,6 +528,7 @@ class TipoVide(models.Model): return '%s: %s' % (self.sigla, self.nome) +@reversion.register() class TipoDispositivo(BaseModel): """ - no attributo rotulo_prefixo_texto, caso haja um ';' (ponto e vírgula), e @@ -729,6 +738,7 @@ class TipoDispositivo(BaseModel): return False +@reversion.register() class TipoDispositivoRelationship(BaseModel): pai = models.ForeignKey(TipoDispositivo, related_name='filhos_permitidos') filho_permitido = models.ForeignKey( @@ -761,6 +771,7 @@ class TipoDispositivoRelationship(BaseModel): self.filho_permitido.nome if self.filho_permitido else '') +@reversion.register() class TipoPublicacao(models.Model): sigla = models.CharField( max_length=10, unique=True, verbose_name=_('Sigla')) @@ -774,6 +785,7 @@ class TipoPublicacao(models.Model): return self.nome +@reversion.register() class VeiculoPublicacao(models.Model): sigla = models.CharField( max_length=10, unique=True, verbose_name=_('Sigla')) @@ -787,6 +799,7 @@ class VeiculoPublicacao(models.Model): return '%s: %s' % (self.sigla, self.nome) +@reversion.register() class Publicacao(TimestampedMixin): ta = models.ForeignKey( TextoArticulado, verbose_name=_('Texto Articulado')) @@ -828,6 +841,7 @@ class Publicacao(TimestampedMixin): self.ta) +@reversion.register() class Dispositivo(BaseModel, TimestampedMixin): TEXTO_PADRAO_DISPOSITIVO_REVOGADO = _('(Revogado)') INTERVALO_ORDEM = 1000 @@ -1603,6 +1617,7 @@ class Dispositivo(BaseModel, TimestampedMixin): ordem_bloco_atualizador=count) +@reversion.register() class Vide(TimestampedMixin): texto = models.TextField(verbose_name=_('Texto do Vide')) @@ -1639,6 +1654,7 @@ NOTAS_PUBLICIDADE_CHOICES = ( ) +@reversion.register() class Nota(TimestampedMixin): NPRIV = 1 diff --git a/sapl/legacy/migration.py b/sapl/legacy/migration.py index 7fece5489..40741412b 100644 --- a/sapl/legacy/migration.py +++ b/sapl/legacy/migration.py @@ -12,6 +12,8 @@ from django.db.models import CharField, Max, ProtectedError, TextField from django.db.models.base import ModelBase from model_mommy import mommy from model_mommy.mommy import foreign_key_required, make +import reversion +from reversion.models import Revision, Version from sapl.base.models import Autor, ProblemaMigracao from sapl.comissoes.models import Comissao, Composicao, Participacao @@ -122,24 +124,28 @@ def get_fk_related(field, value, label=None): pk = 1 if hasattr(field.related_model.objects.last(), 'pk'): pk = field.related_model.objects.last().pk - value = mommy.make( - field.related_model, **fields_dict, - pk=(pk + 1 or 1)) - descricao = 'stub criado para campos não nuláveis!' - save_relation(value, [field.name], msg, descricao, - eh_stub=True) - warn(msg + ' => ' + descricao) + with reversion.create_revision(): + reversion.set_comment('Stub criado pela migração') + value = mommy.make( + field.related_model, **fields_dict, + pk=(pk + 1 or 1)) + descricao = 'stub criado para campos não nuláveis!' + save_relation(value, [field.name], msg, descricao, + eh_stub=True) + warn(msg + ' => ' + descricao) else: value = None else: if field.model._meta.label == 'sessao.RegistroVotacao' and \ field.name == 'ordem': return value - value = make_stub(field.related_model, value) - descricao = 'stub criado para entrada orfã!' - warn(msg + ' => ' + descricao) - save_relation(value, [field.name], msg, descricao, - eh_stub=True) + with reversion.create_revision(): + reversion.set_comment('Stub criado pela migração') + value = make_stub(field.related_model, value) + descricao = 'stub criado para entrada orfã!' + warn(msg + ' => ' + descricao) + save_relation(value, [field.name], msg, descricao, + eh_stub=True) else: assert value return value @@ -308,11 +314,11 @@ class DataMigrator: value = getattr(old, old_field_name) if field_type == 'DateField' and \ not field.null and value is None: - descricao = 'A data 0001-01-01 foi colocada no lugar' + descricao = 'A data 1111-11-11 foi colocada no lugar' problema = 'O valor da data era nulo ou inválido' warn(msg + ' => ' + descricao) - value = '0001-01-01' + value = date(1111, 11, 11) self.data_mudada['obj'] = new self.data_mudada['descricao'] = descricao self.data_mudada['problema'] = problema @@ -334,11 +340,13 @@ class DataMigrator: '(em %s %s)' % ( field.name, value, field.model.__name__, label or '---') - value = make_stub(field.related_model, value) - descricao = 'stub criado para entrada orfã!' - warn(msg + ' => ' + descricao) - save_relation(value, [field.name], msg, descricao, - eh_stub=True) + with reversion.create_revision(): + value = make_stub(field.related_model, value) + descricao = 'stub criado para entrada orfã!' + warn(msg + ' => ' + descricao) + save_relation(value, [field.name], msg, descricao, + eh_stub=True) + reversion.set_comment('Stub criado pela migração') setattr(new, field.name, value) elif field.model.__name__ == 'TipoAutor' and \ field.name == 'content_type': @@ -353,6 +361,8 @@ class DataMigrator: def migrate(self, obj=appconfs): # warning: model/app migration order is of utmost importance self.to_delete = [] + Revision.objects.all().delete() + Version.objects.all().delete() ProblemaMigracao.objects.all().delete() exec_sql_file('sapl/legacy/scripts/fix_tables.sql', 'legacy') get_user_model().objects.exclude(is_superuser=True).delete() @@ -364,15 +374,20 @@ class DataMigrator: while self.to_delete: for obj in self.to_delete: try: - obj.delete() - self.to_delete.remove(obj) + with reversion.create_revision(): + obj.delete() + self.to_delete.remove(obj) + reversion.set_comment( + 'Objeto com ind_excluido deletado') except ProtectedError: - msg = 'A entrada de PK %s da model %s não pode ser ' \ - 'excluida' % (obj.pk, obj._meta.model_name) - descricao = 'Um ou mais objetos protegidos ' - warn(msg + ' => ' + descricao) - save_relation(obj=obj, problema=msg, - descricao=descricao, eh_stub=False) + with reversion.create_revision(): + msg = 'A entrada de PK %s da model %s não pode ser ' \ + 'excluida' % (obj.pk, obj._meta.model_name) + descricao = 'Um ou mais objetos protegidos ' + warn(msg + ' => ' + descricao) + save_relation(obj=obj, problema=msg, + descricao=descricao, eh_stub=False) + reversion.set_comment('Objeto excluído pela migração') info('Deletando stubs desnecessários...') while self.delete_stubs(): @@ -420,13 +435,16 @@ class DataMigrator: if legacy_pk_name == 'id': # There is no pk in the legacy table def save(new, old): - new.save() - + with reversion.create_revision(): + new.save() + reversion.set_comment('Objeto criado pela migração') old_records = iter_sql_records( 'select * from ' + legacy_model._meta.db_table, 'legacy') else: def save(new, old): - save_with_id(new, getattr(old, legacy_pk_name)) + with reversion.create_revision(): + save_with_id(new, getattr(old, legacy_pk_name)) + reversion.set_comment('Objeto criado pela migração') old_records = legacy_model.objects.all().order_by(legacy_pk_name) @@ -443,8 +461,10 @@ class DataMigrator: if ajuste_depois_salvar: ajuste_depois_salvar(new, old) if self.data_mudada: - save_relation(**self.data_mudada) - self.data_mudada.clear() + with reversion.create_revision(): + save_relation(**self.data_mudada) + self.data_mudada.clear() + reversion.set_comment('Ajuste de data pela migração') if getattr(old, 'ind_excluido', False): self.to_delete.append(new) @@ -455,13 +475,17 @@ class DataMigrator: original = obj.content_type.get_all_objects_for_this_type( id=obj.object_id) if stub_desnecessario(original[0]): - qtd_exclusoes, *_ = original.delete() - assert qtd_exclusoes == 1 - qtd_exclusoes, *_ = obj.delete() - assert qtd_exclusoes == 1 - excluidos = excluidos + 1 + with reversion.create_revision(): + qtd_exclusoes, *_ = original.delete() + assert qtd_exclusoes == 1 + qtd_exclusoes, *_ = obj.delete() + assert qtd_exclusoes == 1 + excluidos = excluidos + 1 + reversion.set_comment('Stub desnecessario excluido') elif not obj.content_object and not obj.eh_stub: - qtd_exclusoes, *_ = obj.delete() + with reversion.create_revision(): + qtd_exclusoes, *_ = obj.delete() + reversion.set_comment('Stub desnecessário excluido') assert qtd_exclusoes == 1 excluidos = excluidos + 1 return excluidos @@ -504,7 +528,9 @@ def adjust_participacao(new, old): assert len(already_created) == 1 # we must never have made 2 copies [composicao] = already_created else: - composicao.save() + with reversion.create_revision(): + composicao.save() + reversion.set_comment('Objeto criado pela migração') new.composicao = composicao @@ -570,11 +596,13 @@ def adjust_normajuridica_depois_salvar(new, old): def adjust_protocolo_depois_salvar(new, old): if old.num_protocolo is None: - problema = 'Número do protocolo de PK %s é nulo' % new.pk - descricao = 'Número do protocolo alterado para %s!' % new.numero - warn(problema + ' => ' + descricao) - save_relation(obj=new, problema=problema, - descricao=descricao, eh_stub=False) + with reversion.create_revision(): + problema = 'Número do protocolo de PK %s é nulo' % new.pk + descricao = 'Número do protocolo alterado para %s!' % new.numero + warn(problema + ' => ' + descricao) + save_relation(obj=new, problema=problema, + descricao=descricao, eh_stub=False) + reversion.set_comment('Numero de protocolo teve que ser alterado') def adjust_autor(new, old): @@ -589,7 +617,9 @@ def adjust_autor(new, old): username=old.col_username).exists(): user = get_user_model()( username=old.col_username, password=12345) - user.save() + with reversion.create_revision(): + user.save() + reversion.set_comment('Objeto criado pela migração') new.user = user else: new.user = get_user_model().objects.filter( diff --git a/sapl/lexml/models.py b/sapl/lexml/models.py index b931a5d17..8c30d9ee1 100644 --- a/sapl/lexml/models.py +++ b/sapl/lexml/models.py @@ -1,7 +1,9 @@ from django.db import models from django.utils.translation import ugettext_lazy as _ +import reversion +@reversion.register() class LexmlProvedor(models.Model): # LexmlRegistroProvedor id_provedor = models.PositiveIntegerField(verbose_name=_('Id do provedor')) nome = models.CharField(max_length=255, verbose_name=_('Nome do provedor')) @@ -29,6 +31,7 @@ class LexmlProvedor(models.Model): # LexmlRegistroProvedor return self.nome +@reversion.register() class LexmlPublicador(models.Model): id_publicador = models.PositiveIntegerField( verbose_name=_('Id do publicador')) diff --git a/sapl/materia/migrations/0075_auto_20170123_1548.py b/sapl/materia/migrations/0075_auto_20170123_1548.py new file mode 100644 index 000000000..7a1ca66ea --- /dev/null +++ b/sapl/materia/migrations/0075_auto_20170123_1548.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.7 on 2017-01-23 15:48 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('materia', '0074_auto_20170102_0951'), + ] + + operations = [ + migrations.AlterField( + model_name='materialegislativa', + name='ano', + field=models.PositiveSmallIntegerField(choices=[(2017, 2017), (2016, 2016), (2015, 2015), (2014, 2014), (2013, 2013), (2012, 2012), (2011, 2011), (2010, 2010), (2009, 2009), (2008, 2008), (2007, 2007), (2006, 2006), (2005, 2005), (2004, 2004), (2003, 2003), (2002, 2002), (2001, 2001), (2000, 2000), (1999, 1999), (1998, 1998), (1997, 1997), (1996, 1996), (1995, 1995), (1994, 1994), (1993, 1993), (1992, 1992), (1991, 1991), (1990, 1990), (1989, 1989), (1988, 1988), (1987, 1987), (1986, 1986), (1985, 1985), (1984, 1984), (1983, 1983), (1982, 1982), (1981, 1981), (1980, 1980), (1979, 1979), (1978, 1978), (1977, 1977), (1976, 1976), (1975, 1975), (1974, 1974), (1973, 1973), (1972, 1972), (1971, 1971), (1970, 1970), (1969, 1969), (1968, 1968), (1967, 1967), (1966, 1966), (1965, 1965), (1964, 1964), (1963, 1963), (1962, 1962), (1961, 1961), (1960, 1960), (1959, 1959), (1958, 1958), (1957, 1957), (1956, 1956), (1955, 1955), (1954, 1954), (1953, 1953), (1952, 1952), (1951, 1951), (1950, 1950), (1949, 1949), (1948, 1948), (1947, 1947), (1946, 1946), (1945, 1945), (1944, 1944), (1943, 1943), (1942, 1942), (1941, 1941), (1940, 1940), (1939, 1939), (1938, 1938), (1937, 1937), (1936, 1936), (1935, 1935), (1934, 1934), (1933, 1933), (1932, 1932), (1931, 1931), (1930, 1930), (1929, 1929), (1928, 1928), (1927, 1927), (1926, 1926), (1925, 1925), (1924, 1924), (1923, 1923), (1922, 1922), (1921, 1921), (1920, 1920), (1919, 1919), (1918, 1918), (1917, 1917), (1916, 1916), (1915, 1915), (1914, 1914), (1913, 1913), (1912, 1912), (1911, 1911), (1910, 1910), (1909, 1909), (1908, 1908), (1907, 1907), (1906, 1906), (1905, 1905), (1904, 1904), (1903, 1903), (1902, 1902), (1901, 1901), (1900, 1900), (1899, 1899), (1898, 1898), (1897, 1897), (1896, 1896), (1895, 1895), (1894, 1894), (1893, 1893), (1892, 1892), (1891, 1891), (1890, 1890)], verbose_name='Ano'), + ), + migrations.AlterField( + model_name='materialegislativa', + name='ano_origem_externa', + field=models.PositiveSmallIntegerField(blank=True, choices=[(2017, 2017), (2016, 2016), (2015, 2015), (2014, 2014), (2013, 2013), (2012, 2012), (2011, 2011), (2010, 2010), (2009, 2009), (2008, 2008), (2007, 2007), (2006, 2006), (2005, 2005), (2004, 2004), (2003, 2003), (2002, 2002), (2001, 2001), (2000, 2000), (1999, 1999), (1998, 1998), (1997, 1997), (1996, 1996), (1995, 1995), (1994, 1994), (1993, 1993), (1992, 1992), (1991, 1991), (1990, 1990), (1989, 1989), (1988, 1988), (1987, 1987), (1986, 1986), (1985, 1985), (1984, 1984), (1983, 1983), (1982, 1982), (1981, 1981), (1980, 1980), (1979, 1979), (1978, 1978), (1977, 1977), (1976, 1976), (1975, 1975), (1974, 1974), (1973, 1973), (1972, 1972), (1971, 1971), (1970, 1970), (1969, 1969), (1968, 1968), (1967, 1967), (1966, 1966), (1965, 1965), (1964, 1964), (1963, 1963), (1962, 1962), (1961, 1961), (1960, 1960), (1959, 1959), (1958, 1958), (1957, 1957), (1956, 1956), (1955, 1955), (1954, 1954), (1953, 1953), (1952, 1952), (1951, 1951), (1950, 1950), (1949, 1949), (1948, 1948), (1947, 1947), (1946, 1946), (1945, 1945), (1944, 1944), (1943, 1943), (1942, 1942), (1941, 1941), (1940, 1940), (1939, 1939), (1938, 1938), (1937, 1937), (1936, 1936), (1935, 1935), (1934, 1934), (1933, 1933), (1932, 1932), (1931, 1931), (1930, 1930), (1929, 1929), (1928, 1928), (1927, 1927), (1926, 1926), (1925, 1925), (1924, 1924), (1923, 1923), (1922, 1922), (1921, 1921), (1920, 1920), (1919, 1919), (1918, 1918), (1917, 1917), (1916, 1916), (1915, 1915), (1914, 1914), (1913, 1913), (1912, 1912), (1911, 1911), (1910, 1910), (1909, 1909), (1908, 1908), (1907, 1907), (1906, 1906), (1905, 1905), (1904, 1904), (1903, 1903), (1902, 1902), (1901, 1901), (1900, 1900), (1899, 1899), (1898, 1898), (1897, 1897), (1896, 1896), (1895, 1895), (1894, 1894), (1893, 1893), (1892, 1892), (1891, 1891), (1890, 1890)], null=True, verbose_name='Ano'), + ), + migrations.AlterField( + model_name='numeracao', + name='ano_materia', + field=models.PositiveSmallIntegerField(choices=[(2017, 2017), (2016, 2016), (2015, 2015), (2014, 2014), (2013, 2013), (2012, 2012), (2011, 2011), (2010, 2010), (2009, 2009), (2008, 2008), (2007, 2007), (2006, 2006), (2005, 2005), (2004, 2004), (2003, 2003), (2002, 2002), (2001, 2001), (2000, 2000), (1999, 1999), (1998, 1998), (1997, 1997), (1996, 1996), (1995, 1995), (1994, 1994), (1993, 1993), (1992, 1992), (1991, 1991), (1990, 1990), (1989, 1989), (1988, 1988), (1987, 1987), (1986, 1986), (1985, 1985), (1984, 1984), (1983, 1983), (1982, 1982), (1981, 1981), (1980, 1980), (1979, 1979), (1978, 1978), (1977, 1977), (1976, 1976), (1975, 1975), (1974, 1974), (1973, 1973), (1972, 1972), (1971, 1971), (1970, 1970), (1969, 1969), (1968, 1968), (1967, 1967), (1966, 1966), (1965, 1965), (1964, 1964), (1963, 1963), (1962, 1962), (1961, 1961), (1960, 1960), (1959, 1959), (1958, 1958), (1957, 1957), (1956, 1956), (1955, 1955), (1954, 1954), (1953, 1953), (1952, 1952), (1951, 1951), (1950, 1950), (1949, 1949), (1948, 1948), (1947, 1947), (1946, 1946), (1945, 1945), (1944, 1944), (1943, 1943), (1942, 1942), (1941, 1941), (1940, 1940), (1939, 1939), (1938, 1938), (1937, 1937), (1936, 1936), (1935, 1935), (1934, 1934), (1933, 1933), (1932, 1932), (1931, 1931), (1930, 1930), (1929, 1929), (1928, 1928), (1927, 1927), (1926, 1926), (1925, 1925), (1924, 1924), (1923, 1923), (1922, 1922), (1921, 1921), (1920, 1920), (1919, 1919), (1918, 1918), (1917, 1917), (1916, 1916), (1915, 1915), (1914, 1914), (1913, 1913), (1912, 1912), (1911, 1911), (1910, 1910), (1909, 1909), (1908, 1908), (1907, 1907), (1906, 1906), (1905, 1905), (1904, 1904), (1903, 1903), (1902, 1902), (1901, 1901), (1900, 1900), (1899, 1899), (1898, 1898), (1897, 1897), (1896, 1896), (1895, 1895), (1894, 1894), (1893, 1893), (1892, 1892), (1891, 1891), (1890, 1890)], verbose_name='Ano'), + ), + migrations.AlterField( + model_name='proposicao', + name='ano', + field=models.PositiveSmallIntegerField(blank=True, choices=[(2017, 2017), (2016, 2016), (2015, 2015), (2014, 2014), (2013, 2013), (2012, 2012), (2011, 2011), (2010, 2010), (2009, 2009), (2008, 2008), (2007, 2007), (2006, 2006), (2005, 2005), (2004, 2004), (2003, 2003), (2002, 2002), (2001, 2001), (2000, 2000), (1999, 1999), (1998, 1998), (1997, 1997), (1996, 1996), (1995, 1995), (1994, 1994), (1993, 1993), (1992, 1992), (1991, 1991), (1990, 1990), (1989, 1989), (1988, 1988), (1987, 1987), (1986, 1986), (1985, 1985), (1984, 1984), (1983, 1983), (1982, 1982), (1981, 1981), (1980, 1980), (1979, 1979), (1978, 1978), (1977, 1977), (1976, 1976), (1975, 1975), (1974, 1974), (1973, 1973), (1972, 1972), (1971, 1971), (1970, 1970), (1969, 1969), (1968, 1968), (1967, 1967), (1966, 1966), (1965, 1965), (1964, 1964), (1963, 1963), (1962, 1962), (1961, 1961), (1960, 1960), (1959, 1959), (1958, 1958), (1957, 1957), (1956, 1956), (1955, 1955), (1954, 1954), (1953, 1953), (1952, 1952), (1951, 1951), (1950, 1950), (1949, 1949), (1948, 1948), (1947, 1947), (1946, 1946), (1945, 1945), (1944, 1944), (1943, 1943), (1942, 1942), (1941, 1941), (1940, 1940), (1939, 1939), (1938, 1938), (1937, 1937), (1936, 1936), (1935, 1935), (1934, 1934), (1933, 1933), (1932, 1932), (1931, 1931), (1930, 1930), (1929, 1929), (1928, 1928), (1927, 1927), (1926, 1926), (1925, 1925), (1924, 1924), (1923, 1923), (1922, 1922), (1921, 1921), (1920, 1920), (1919, 1919), (1918, 1918), (1917, 1917), (1916, 1916), (1915, 1915), (1914, 1914), (1913, 1913), (1912, 1912), (1911, 1911), (1910, 1910), (1909, 1909), (1908, 1908), (1907, 1907), (1906, 1906), (1905, 1905), (1904, 1904), (1903, 1903), (1902, 1902), (1901, 1901), (1900, 1900), (1899, 1899), (1898, 1898), (1897, 1897), (1896, 1896), (1895, 1895), (1894, 1894), (1893, 1893), (1892, 1892), (1891, 1891), (1890, 1890)], default=None, null=True, verbose_name='Ano'), + ), + ] diff --git a/sapl/materia/models.py b/sapl/materia/models.py index e18f662d6..c0d5f3383 100644 --- a/sapl/materia/models.py +++ b/sapl/materia/models.py @@ -8,6 +8,7 @@ from django.db.models.deletion import PROTECT from django.utils import formats from django.utils.translation import ugettext_lazy as _ from model_utils import Choices +import reversion from sapl.base.models import Autor from sapl.comissoes.models import Comissao @@ -30,6 +31,7 @@ def grupo_autor(): return grupo.id +@reversion.register() class TipoProposicao(models.Model): descricao = models.CharField(max_length=50, verbose_name=_('Descrição')) @@ -63,6 +65,7 @@ class TipoProposicao(models.Model): return self.descricao +@reversion.register() class TipoMateriaLegislativa(models.Model): sigla = models.CharField(max_length=5, verbose_name=_('Sigla')) descricao = models.CharField(max_length=50, verbose_name=_('Descrição ')) @@ -88,6 +91,7 @@ class TipoMateriaLegislativa(models.Model): return self.descricao +@reversion.register() class RegimeTramitacao(models.Model): descricao = models.CharField(max_length=50, verbose_name=_('Descrição')) @@ -99,6 +103,7 @@ class RegimeTramitacao(models.Model): return self.descricao +@reversion.register() class Origem(models.Model): sigla = models.CharField(max_length=10, verbose_name=_('Sigla')) nome = models.CharField(max_length=50, verbose_name=_('Nome')) @@ -115,6 +120,7 @@ TIPO_APRESENTACAO_CHOICES = Choices(('O', 'oral', _('Oral')), ('E', 'escrita', _('Escrita'))) +@reversion.register() class MateriaLegislativa(models.Model): tipo = models.ForeignKey(TipoMateriaLegislativa, verbose_name=_('Tipo')) @@ -228,6 +234,7 @@ class MateriaLegislativa(models.Model): update_fields=update_fields) +@reversion.register() class Autoria(models.Model): autor = models.ForeignKey(Autor, verbose_name=_('Autor')) materia = models.ForeignKey( @@ -245,6 +252,7 @@ class Autoria(models.Model): 'autor': self.autor, 'materia': self.materia} +@reversion.register() class AcompanhamentoMateria(models.Model): usuario = models.CharField(max_length=50) materia = models.ForeignKey(MateriaLegislativa) @@ -264,6 +272,7 @@ class AcompanhamentoMateria(models.Model): 'materia': self.materia, 'hash': self.hash} +@reversion.register() class Anexada(models.Model): materia_principal = models.ForeignKey( MateriaLegislativa, related_name='materia_principal_set') @@ -284,6 +293,7 @@ class Anexada(models.Model): 'materia_anexada': self.materia_anexada} +@reversion.register() class AssuntoMateria(models.Model): assunto = models.CharField(max_length=200) dispositivo = models.CharField(max_length=50) @@ -296,6 +306,7 @@ class AssuntoMateria(models.Model): return self.assunto +@reversion.register() class DespachoInicial(models.Model): # TODO M2M? # TODO Despachos não são necessáriamente comissoes, podem ser outros @@ -313,6 +324,7 @@ class DespachoInicial(models.Model): 'comissao': self.comissao} +@reversion.register() class TipoDocumento(models.Model): descricao = models.CharField( max_length=50, verbose_name=_('Tipo Documento')) @@ -332,6 +344,7 @@ class TipoDocumento(models.Model): return self.descricao +@reversion.register() class DocumentoAcessorio(models.Model): materia = models.ForeignKey(MateriaLegislativa) tipo = models.ForeignKey(TipoDocumento, verbose_name=_('Tipo')) @@ -384,6 +397,7 @@ class DocumentoAcessorio(models.Model): update_fields=update_fields) +@reversion.register() class MateriaAssunto(models.Model): # TODO M2M ?? assunto = models.ForeignKey(AssuntoMateria) @@ -398,6 +412,7 @@ class MateriaAssunto(models.Model): 'materia': self.materia, 'assunto': self.assunto} +@reversion.register() class Numeracao(models.Model): materia = models.ForeignKey(MateriaLegislativa) tipo_materia = models.ForeignKey( @@ -423,6 +438,7 @@ class Numeracao(models.Model): 'ano': self.data_materia.year} +@reversion.register() class Orgao(models.Model): nome = models.CharField(max_length=60, verbose_name=_('Nome')) sigla = models.CharField(max_length=10, verbose_name=_('Sigla')) @@ -450,6 +466,7 @@ class Orgao(models.Model): '%(nome)s - %(sigla)s') % {'nome': self.nome, 'sigla': self.sigla} +@reversion.register() class TipoFimRelatoria(models.Model): descricao = models.CharField( max_length=50, verbose_name=_('Tipo Fim Relatoria')) @@ -462,6 +479,7 @@ class TipoFimRelatoria(models.Model): return self.descricao +@reversion.register() class Relatoria(models.Model): materia = models.ForeignKey(MateriaLegislativa) parlamentar = models.ForeignKey(Parlamentar, verbose_name=_('Parlamentar')) @@ -488,6 +506,7 @@ class Relatoria(models.Model): 'data': self.data_designacao_relator} +@reversion.register() class Parecer(models.Model): relatoria = models.ForeignKey(Relatoria) materia = models.ForeignKey(MateriaLegislativa) @@ -506,6 +525,7 @@ class Parecer(models.Model): } +@reversion.register() class Proposicao(models.Model): autor = models.ForeignKey(Autor, null=True, blank=True, on_delete=PROTECT) tipo = models.ForeignKey(TipoProposicao, verbose_name=_('Tipo')) @@ -642,6 +662,7 @@ class Proposicao(models.Model): update_fields=update_fields) +@reversion.register() class StatusTramitacao(models.Model): INDICADOR_CHOICES = Choices(('F', 'fim', _('Fim')), ('R', 'retorno', _('Retorno'))) @@ -663,6 +684,7 @@ class StatusTramitacao(models.Model): 'descricao': self.descricao} +@reversion.register() class UnidadeTramitacao(models.Model): comissao = models.ForeignKey( Comissao, blank=True, null=True, verbose_name=_('Comissão')) @@ -701,6 +723,7 @@ class UnidadeTramitacao(models.Model): return _('%(parlamentar)s') % {'parlamentar': self.parlamentar} +@reversion.register() class Tramitacao(models.Model): TURNO_CHOICES = Choices( ('P', 'primeiro', _('Primeiro')), diff --git a/sapl/norma/migrations/0033_auto_20170123_1548.py b/sapl/norma/migrations/0033_auto_20170123_1548.py new file mode 100644 index 000000000..918c476c9 --- /dev/null +++ b/sapl/norma/migrations/0033_auto_20170123_1548.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.7 on 2017-01-23 15:48 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('norma', '0032_merge'), + ] + + operations = [ + migrations.AlterField( + model_name='normajuridica', + name='ano', + field=models.PositiveSmallIntegerField(choices=[(2017, 2017), (2016, 2016), (2015, 2015), (2014, 2014), (2013, 2013), (2012, 2012), (2011, 2011), (2010, 2010), (2009, 2009), (2008, 2008), (2007, 2007), (2006, 2006), (2005, 2005), (2004, 2004), (2003, 2003), (2002, 2002), (2001, 2001), (2000, 2000), (1999, 1999), (1998, 1998), (1997, 1997), (1996, 1996), (1995, 1995), (1994, 1994), (1993, 1993), (1992, 1992), (1991, 1991), (1990, 1990), (1989, 1989), (1988, 1988), (1987, 1987), (1986, 1986), (1985, 1985), (1984, 1984), (1983, 1983), (1982, 1982), (1981, 1981), (1980, 1980), (1979, 1979), (1978, 1978), (1977, 1977), (1976, 1976), (1975, 1975), (1974, 1974), (1973, 1973), (1972, 1972), (1971, 1971), (1970, 1970), (1969, 1969), (1968, 1968), (1967, 1967), (1966, 1966), (1965, 1965), (1964, 1964), (1963, 1963), (1962, 1962), (1961, 1961), (1960, 1960), (1959, 1959), (1958, 1958), (1957, 1957), (1956, 1956), (1955, 1955), (1954, 1954), (1953, 1953), (1952, 1952), (1951, 1951), (1950, 1950), (1949, 1949), (1948, 1948), (1947, 1947), (1946, 1946), (1945, 1945), (1944, 1944), (1943, 1943), (1942, 1942), (1941, 1941), (1940, 1940), (1939, 1939), (1938, 1938), (1937, 1937), (1936, 1936), (1935, 1935), (1934, 1934), (1933, 1933), (1932, 1932), (1931, 1931), (1930, 1930), (1929, 1929), (1928, 1928), (1927, 1927), (1926, 1926), (1925, 1925), (1924, 1924), (1923, 1923), (1922, 1922), (1921, 1921), (1920, 1920), (1919, 1919), (1918, 1918), (1917, 1917), (1916, 1916), (1915, 1915), (1914, 1914), (1913, 1913), (1912, 1912), (1911, 1911), (1910, 1910), (1909, 1909), (1908, 1908), (1907, 1907), (1906, 1906), (1905, 1905), (1904, 1904), (1903, 1903), (1902, 1902), (1901, 1901), (1900, 1900), (1899, 1899), (1898, 1898), (1897, 1897), (1896, 1896), (1895, 1895), (1894, 1894), (1893, 1893), (1892, 1892), (1891, 1891), (1890, 1890)], verbose_name='Ano'), + ), + ] diff --git a/sapl/norma/models.py b/sapl/norma/models.py index a36368e8b..4617d04d6 100644 --- a/sapl/norma/models.py +++ b/sapl/norma/models.py @@ -3,12 +3,14 @@ from django.db import models from django.template import defaultfilters from django.utils.translation import ugettext_lazy as _ from model_utils import Choices +import reversion from sapl.compilacao.models import TextoArticulado from sapl.materia.models import MateriaLegislativa from sapl.utils import RANGE_ANOS, YES_NO_CHOICES, texto_upload_path +@reversion.register() class AssuntoNorma(models.Model): assunto = models.CharField(max_length=50, verbose_name=_('Assunto')) descricao = models.CharField( @@ -22,6 +24,7 @@ class AssuntoNorma(models.Model): return self.assunto +@reversion.register() class TipoNormaJuridica(models.Model): # TODO transform into Domain Model and use an FK for the field EQUIVALENTE_LEXML_CHOICES = ((name, name) for name in @@ -56,6 +59,7 @@ class TipoNormaJuridica(models.Model): return self.descricao +@reversion.register() class NormaJuridica(models.Model): ESFERA_FEDERACAO_CHOICES = Choices( ('E', 'estadual', _('Estadual')), @@ -145,6 +149,7 @@ class NormaJuridica(models.Model): update_fields=update_fields) +@reversion.register() class LegislacaoCitada(models.Model): materia = models.ForeignKey(MateriaLegislativa) norma = models.ForeignKey(NormaJuridica) @@ -181,6 +186,7 @@ class LegislacaoCitada(models.Model): return str(self.norma) +@reversion.register() class TipoVinculoNormaJuridica(models.Model): sigla = models.CharField( max_length=1, blank=True, verbose_name=_('Sigla')) @@ -197,6 +203,7 @@ class TipoVinculoNormaJuridica(models.Model): return self.descricao_ativa +@reversion.register() class NormaRelacionada(models.Model): norma_principal = models.ForeignKey( NormaJuridica, diff --git a/sapl/painel/models.py b/sapl/painel/models.py index 222dd3bae..0f3427f3a 100644 --- a/sapl/painel/models.py +++ b/sapl/painel/models.py @@ -1,7 +1,9 @@ from django.db import models from django.utils.translation import ugettext_lazy as _ +import reversion +@reversion.register() class Painel(models.Model): PAINEL_TYPES = ( ('C', 'Completo'), @@ -19,6 +21,7 @@ class Painel(models.Model): return str(self.aberto) + ":" + self.data_painel.strftime("%d/%m/%Y") +@reversion.register() class Cronometro(models.Model): CRONOMETRO_TYPES = ( ('A', _('Aparte')), diff --git a/sapl/parlamentares/models.py b/sapl/parlamentares/models.py index 63177a734..2bc000984 100644 --- a/sapl/parlamentares/models.py +++ b/sapl/parlamentares/models.py @@ -4,6 +4,7 @@ from django.contrib.auth.models import User from django.db import models from django.utils.translation import ugettext_lazy as _ from model_utils import Choices +import reversion from sapl.base.models import Autor from sapl.utils import (INDICADOR_AFASTAMENTO, UF, YES_NO_CHOICES, @@ -11,6 +12,7 @@ from sapl.utils import (INDICADOR_AFASTAMENTO, UF, YES_NO_CHOICES, restringe_tipos_de_arquivo_img) +@reversion.register() class Legislatura(models.Model): numero = models.PositiveIntegerField(verbose_name=_('Número')) data_inicio = models.DateField(verbose_name=_('Data Início')) @@ -43,6 +45,7 @@ class Legislatura(models.Model): 'current': current} +@reversion.register() class SessaoLegislativa(models.Model): TIPO_SESSAO_CHOICES = Choices( ('O', 'ordinaria', _('Ordinária')), @@ -74,6 +77,7 @@ class SessaoLegislativa(models.Model): 'fim': self.data_fim.year} +@reversion.register() class Coligacao(models.Model): legislatura = models.ForeignKey(Legislatura, verbose_name=_('Legislatura')) nome = models.CharField(max_length=50, verbose_name=_('Nome')) @@ -96,6 +100,7 @@ def logo_upload_path(instance, filename): return get_logo_media_path(instance, 'logo', filename) +@reversion.register() class Partido(models.Model): sigla = models.CharField(max_length=9, verbose_name=_('Sigla')) nome = models.CharField(max_length=50, verbose_name=_('Nome')) @@ -120,6 +125,7 @@ class Partido(models.Model): } +@reversion.register() class ComposicaoColigacao(models.Model): # TODO M2M partido = models.ForeignKey(Partido, @@ -136,6 +142,7 @@ class ComposicaoColigacao(models.Model): } +@reversion.register() class Municipio(models.Model): # Localidade # TODO filter on migration leaving only cities @@ -164,6 +171,7 @@ class Municipio(models.Model): # Localidade } +@reversion.register() class NivelInstrucao(models.Model): descricao = models.CharField( max_length=50, verbose_name=_('Nível de Instrução')) @@ -176,6 +184,7 @@ class NivelInstrucao(models.Model): return self.descricao +@reversion.register() class SituacaoMilitar(models.Model): descricao = models.CharField( max_length=50, verbose_name=_('Situação Militar')) @@ -196,6 +205,7 @@ def foto_upload_path(instance, filename): return get_foto_media_path(instance, 'foto', filename) +@reversion.register() class Parlamentar(models.Model): FEMININO = 'F' MASCULINO = 'M' @@ -312,6 +322,7 @@ class Parlamentar(models.Model): + self.fotografia.url + '>'if self.fotografia else '' +@reversion.register() class TipoDependente(models.Model): descricao = models.CharField(max_length=50, verbose_name=_('Descrição')) @@ -323,6 +334,7 @@ class TipoDependente(models.Model): return self.descricao +@reversion.register() class Dependente(models.Model): FEMININO = 'F' MASCULINO = 'M' @@ -353,6 +365,7 @@ class Dependente(models.Model): return self.nome +@reversion.register() class Filiacao(models.Model): data = models.DateField(verbose_name=_('Data Filiação')) parlamentar = models.ForeignKey(Parlamentar) @@ -373,6 +386,7 @@ class Filiacao(models.Model): } +@reversion.register() class TipoAfastamento(models.Model): descricao = models.CharField(max_length=50, verbose_name=_('Descrição')) indicador = models.CharField( @@ -389,6 +403,7 @@ class TipoAfastamento(models.Model): return self.descricao +@reversion.register() class Mandato(models.Model): parlamentar = models.ForeignKey(Parlamentar) tipo_afastamento = models.ForeignKey( @@ -427,6 +442,7 @@ class Mandato(models.Model): f.data_desfiliacao or datetime.max.date())] +@reversion.register() class CargoMesa(models.Model): # TODO M2M ???? descricao = models.CharField( @@ -442,6 +458,7 @@ class CargoMesa(models.Model): return self.descricao +@reversion.register() class ComposicaoMesa(models.Model): # TODO M2M ???? Ternary????? parlamentar = models.ForeignKey(Parlamentar) @@ -458,6 +475,7 @@ class ComposicaoMesa(models.Model): } +@reversion.register() class Frente(models.Model): ''' * Uma frente agrupa vários parlamentares diff --git a/sapl/protocoloadm/migrations/0010_auto_20170123_1548.py b/sapl/protocoloadm/migrations/0010_auto_20170123_1548.py new file mode 100644 index 000000000..05dafb21c --- /dev/null +++ b/sapl/protocoloadm/migrations/0010_auto_20170123_1548.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.7 on 2017-01-23 15:48 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('protocoloadm', '0009_auto_20170102_0951'), + ] + + operations = [ + migrations.AlterField( + model_name='documentoadministrativo', + name='ano', + field=models.PositiveSmallIntegerField(choices=[(2017, 2017), (2016, 2016), (2015, 2015), (2014, 2014), (2013, 2013), (2012, 2012), (2011, 2011), (2010, 2010), (2009, 2009), (2008, 2008), (2007, 2007), (2006, 2006), (2005, 2005), (2004, 2004), (2003, 2003), (2002, 2002), (2001, 2001), (2000, 2000), (1999, 1999), (1998, 1998), (1997, 1997), (1996, 1996), (1995, 1995), (1994, 1994), (1993, 1993), (1992, 1992), (1991, 1991), (1990, 1990), (1989, 1989), (1988, 1988), (1987, 1987), (1986, 1986), (1985, 1985), (1984, 1984), (1983, 1983), (1982, 1982), (1981, 1981), (1980, 1980), (1979, 1979), (1978, 1978), (1977, 1977), (1976, 1976), (1975, 1975), (1974, 1974), (1973, 1973), (1972, 1972), (1971, 1971), (1970, 1970), (1969, 1969), (1968, 1968), (1967, 1967), (1966, 1966), (1965, 1965), (1964, 1964), (1963, 1963), (1962, 1962), (1961, 1961), (1960, 1960), (1959, 1959), (1958, 1958), (1957, 1957), (1956, 1956), (1955, 1955), (1954, 1954), (1953, 1953), (1952, 1952), (1951, 1951), (1950, 1950), (1949, 1949), (1948, 1948), (1947, 1947), (1946, 1946), (1945, 1945), (1944, 1944), (1943, 1943), (1942, 1942), (1941, 1941), (1940, 1940), (1939, 1939), (1938, 1938), (1937, 1937), (1936, 1936), (1935, 1935), (1934, 1934), (1933, 1933), (1932, 1932), (1931, 1931), (1930, 1930), (1929, 1929), (1928, 1928), (1927, 1927), (1926, 1926), (1925, 1925), (1924, 1924), (1923, 1923), (1922, 1922), (1921, 1921), (1920, 1920), (1919, 1919), (1918, 1918), (1917, 1917), (1916, 1916), (1915, 1915), (1914, 1914), (1913, 1913), (1912, 1912), (1911, 1911), (1910, 1910), (1909, 1909), (1908, 1908), (1907, 1907), (1906, 1906), (1905, 1905), (1904, 1904), (1903, 1903), (1902, 1902), (1901, 1901), (1900, 1900), (1899, 1899), (1898, 1898), (1897, 1897), (1896, 1896), (1895, 1895), (1894, 1894), (1893, 1893), (1892, 1892), (1891, 1891), (1890, 1890)], verbose_name='Ano'), + ), + migrations.AlterField( + model_name='protocolo', + name='ano', + field=models.PositiveSmallIntegerField(choices=[(2017, 2017), (2016, 2016), (2015, 2015), (2014, 2014), (2013, 2013), (2012, 2012), (2011, 2011), (2010, 2010), (2009, 2009), (2008, 2008), (2007, 2007), (2006, 2006), (2005, 2005), (2004, 2004), (2003, 2003), (2002, 2002), (2001, 2001), (2000, 2000), (1999, 1999), (1998, 1998), (1997, 1997), (1996, 1996), (1995, 1995), (1994, 1994), (1993, 1993), (1992, 1992), (1991, 1991), (1990, 1990), (1989, 1989), (1988, 1988), (1987, 1987), (1986, 1986), (1985, 1985), (1984, 1984), (1983, 1983), (1982, 1982), (1981, 1981), (1980, 1980), (1979, 1979), (1978, 1978), (1977, 1977), (1976, 1976), (1975, 1975), (1974, 1974), (1973, 1973), (1972, 1972), (1971, 1971), (1970, 1970), (1969, 1969), (1968, 1968), (1967, 1967), (1966, 1966), (1965, 1965), (1964, 1964), (1963, 1963), (1962, 1962), (1961, 1961), (1960, 1960), (1959, 1959), (1958, 1958), (1957, 1957), (1956, 1956), (1955, 1955), (1954, 1954), (1953, 1953), (1952, 1952), (1951, 1951), (1950, 1950), (1949, 1949), (1948, 1948), (1947, 1947), (1946, 1946), (1945, 1945), (1944, 1944), (1943, 1943), (1942, 1942), (1941, 1941), (1940, 1940), (1939, 1939), (1938, 1938), (1937, 1937), (1936, 1936), (1935, 1935), (1934, 1934), (1933, 1933), (1932, 1932), (1931, 1931), (1930, 1930), (1929, 1929), (1928, 1928), (1927, 1927), (1926, 1926), (1925, 1925), (1924, 1924), (1923, 1923), (1922, 1922), (1921, 1921), (1920, 1920), (1919, 1919), (1918, 1918), (1917, 1917), (1916, 1916), (1915, 1915), (1914, 1914), (1913, 1913), (1912, 1912), (1911, 1911), (1910, 1910), (1909, 1909), (1908, 1908), (1907, 1907), (1906, 1906), (1905, 1905), (1904, 1904), (1903, 1903), (1902, 1902), (1901, 1901), (1900, 1900), (1899, 1899), (1898, 1898), (1897, 1897), (1896, 1896), (1895, 1895), (1894, 1894), (1893, 1893), (1892, 1892), (1891, 1891), (1890, 1890)], verbose_name='Ano do Protocolo'), + ), + ] diff --git a/sapl/protocoloadm/models.py b/sapl/protocoloadm/models.py index f3d0a56c2..d73b71344 100644 --- a/sapl/protocoloadm/models.py +++ b/sapl/protocoloadm/models.py @@ -1,12 +1,14 @@ from django.db import models from django.utils.translation import ugettext_lazy as _ from model_utils import Choices +import reversion from sapl.base.models import Autor from sapl.materia.models import TipoMateriaLegislativa, UnidadeTramitacao from sapl.utils import RANGE_ANOS, YES_NO_CHOICES, texto_upload_path +@reversion.register() class TipoDocumentoAdministrativo(models.Model): sigla = models.CharField(max_length=5, verbose_name=_('Sigla')) descricao = models.CharField(max_length=50, verbose_name=_('Descrição')) @@ -45,6 +47,7 @@ def texto_upload_path(instance, filename): """ +@reversion.register() class DocumentoAdministrativo(models.Model): tipo = models.ForeignKey( TipoDocumentoAdministrativo, verbose_name=_('Tipo Documento')) @@ -107,6 +110,7 @@ class DocumentoAdministrativo(models.Model): update_fields=update_fields) +@reversion.register() class DocumentoAcessorioAdministrativo(models.Model): documento = models.ForeignKey(DocumentoAdministrativo) tipo = models.ForeignKey( @@ -156,6 +160,7 @@ class DocumentoAcessorioAdministrativo(models.Model): update_fields=update_fields) +@reversion.register() class Protocolo(models.Model): numero = models.PositiveIntegerField( blank=False, null=False, verbose_name=_('Número de Protocolo')) @@ -203,6 +208,7 @@ class Protocolo(models.Model): ) +@reversion.register() class StatusTramitacaoAdministrativo(models.Model): INDICADOR_CHOICES = Choices( ('F', 'fim', _('Fim')), @@ -225,6 +231,7 @@ class StatusTramitacaoAdministrativo(models.Model): return self.descricao +@reversion.register() class TramitacaoAdministrativo(models.Model): status = models.ForeignKey( StatusTramitacaoAdministrativo, diff --git a/sapl/sessao/models.py b/sapl/sessao/models.py index 369b5a0e2..aab0e3850 100644 --- a/sapl/sessao/models.py +++ b/sapl/sessao/models.py @@ -2,6 +2,7 @@ from django.contrib.auth.models import User from django.db import models from django.utils.translation import ugettext_lazy as _ from model_utils import Choices +import reversion from sapl.base.models import Autor from sapl.materia.models import MateriaLegislativa @@ -11,6 +12,7 @@ from sapl.utils import (YES_NO_CHOICES, SaplGenericRelation, restringe_tipos_de_arquivo_txt, texto_upload_path) +@reversion.register() class CargoBancada(models.Model): nome_cargo = models.CharField(max_length=80, verbose_name=_('Cargo de Bancada')) @@ -27,6 +29,7 @@ class CargoBancada(models.Model): return self.nome_cargo +@reversion.register() class Bancada(models.Model): legislatura = models.ForeignKey(Legislatura, verbose_name=_('Legislatura')) nome = models.CharField( @@ -59,6 +62,7 @@ class Bancada(models.Model): return self.nome +@reversion.register() class TipoSessaoPlenaria(models.Model): nome = models.CharField(max_length=30, verbose_name=_('Tipo')) quorum_minimo = models.PositiveIntegerField( @@ -91,6 +95,7 @@ def anexo_upload_path(instance, filename): # return get_sessao_media_path(instance, 'anexo', filename) +@reversion.register() class SessaoPlenaria(models.Model): # TODO trash??? Seems to have been a FK in the past. Would be: # andamento_sessao = models.ForeignKey( @@ -172,8 +177,13 @@ class SessaoPlenaria(models.Model): def save(self, force_insert=False, force_update=False, using=None, update_fields=None): +<<<<<<< 0d281b8f594224dfa3ede0c7e6ccb32395bdfe42 if not self.pk and (self.upload_pauta or self.upload_ata or self.upload_anexo): +======= + if not self.pk and (self.upload_pauta or self.upload_ata or + self.upload_anexo): +>>>>>>> Migra usando django-reversion upload_pauta = self.upload_pauta upload_ata = self.upload_ata upload_anexo = self.upload_anexo @@ -195,6 +205,7 @@ class SessaoPlenaria(models.Model): update_fields=update_fields) +@reversion.register() class AbstractOrdemDia(models.Model): TIPO_VOTACAO_CHOICES = Choices( (1, 'simbolica', (('Simbólica'))), @@ -224,6 +235,7 @@ class AbstractOrdemDia(models.Model): return '%s - %s' % (self.numero_ordem, self.sessao_plenaria) +@reversion.register() class ExpedienteMateria(AbstractOrdemDia): class Meta: @@ -232,6 +244,7 @@ class ExpedienteMateria(AbstractOrdemDia): ordering = ['numero_ordem'] +@reversion.register() class TipoExpediente(models.Model): nome = models.CharField(max_length=100, verbose_name=_('Tipo')) @@ -243,6 +256,7 @@ class TipoExpediente(models.Model): return self.nome +@reversion.register() class ExpedienteSessao(models.Model): # ExpedienteSessaoPlenaria sessao_plenaria = models.ForeignKey(SessaoPlenaria) tipo = models.ForeignKey(TipoExpediente) @@ -257,6 +271,7 @@ class ExpedienteSessao(models.Model): # ExpedienteSessaoPlenaria return '%s - %s' % (self.tipo, self.sessao_plenaria) +@reversion.register() class IntegranteMesa(models.Model): # MesaSessaoPlenaria sessao_plenaria = models.ForeignKey(SessaoPlenaria) cargo = models.ForeignKey(CargoMesa) @@ -270,6 +285,7 @@ class IntegranteMesa(models.Model): # MesaSessaoPlenaria return '%s - %s' % (self.cargo, self.parlamentar) +@reversion.register() class AbstractOrador(models.Model): # Oradores sessao_plenaria = models.ForeignKey(SessaoPlenaria) parlamentar = models.ForeignKey(Parlamentar, verbose_name=_('Parlamentar')) @@ -289,6 +305,7 @@ class AbstractOrador(models.Model): # Oradores 'numero': self.numero_ordem} +@reversion.register() class Orador(AbstractOrador): # Oradores class Meta: @@ -296,6 +313,7 @@ class Orador(AbstractOrador): # Oradores verbose_name_plural = _('Oradores das Explicações Pessoais') +@reversion.register() class OradorExpediente(AbstractOrador): # OradoresExpediente class Meta: @@ -303,6 +321,7 @@ class OradorExpediente(AbstractOrador): # OradoresExpediente verbose_name_plural = _('Oradores do Expediente') +@reversion.register() class OrdemDia(AbstractOrdemDia): class Meta: @@ -311,6 +330,7 @@ class OrdemDia(AbstractOrdemDia): ordering = ['numero_ordem'] +@reversion.register() class PresencaOrdemDia(models.Model): # OrdemDiaPresenca sessao_plenaria = models.ForeignKey(SessaoPlenaria) parlamentar = models.ForeignKey(Parlamentar) @@ -327,6 +347,7 @@ class PresencaOrdemDia(models.Model): # OrdemDiaPresenca 'parlamentar': self.parlamentar} +@reversion.register() class TipoResultadoVotacao(models.Model): nome = models.CharField(max_length=100, verbose_name=_('Tipo')) @@ -338,6 +359,7 @@ class TipoResultadoVotacao(models.Model): return self.nome +@reversion.register() class RegistroVotacao(models.Model): tipo_resultado_votacao = models.ForeignKey( TipoResultadoVotacao, verbose_name=_('Resultado da Votação')) @@ -363,6 +385,7 @@ class RegistroVotacao(models.Model): 'materia': self.materia} +@reversion.register() class VotoParlamentar(models.Model): # RegistroVotacaoParlamentar votacao = models.ForeignKey(RegistroVotacao) parlamentar = models.ForeignKey(Parlamentar) @@ -378,6 +401,7 @@ class VotoParlamentar(models.Model): # RegistroVotacaoParlamentar 'votacao': self.votacao, 'parlamentar': self.parlamentar} +@reversion.register() class VotoNominal(models.Model): parlamentar = models.ForeignKey(Parlamentar) voto = models.CharField(verbose_name=_('Voto'), max_length=10) @@ -398,6 +422,7 @@ class VotoNominal(models.Model): return '%s - %s' % (self.parlamentar.nome_parlamentar, self.voto) +@reversion.register() class SessaoPlenariaPresenca(models.Model): sessao_plenaria = models.ForeignKey(SessaoPlenaria) parlamentar = models.ForeignKey(Parlamentar) @@ -409,6 +434,7 @@ class SessaoPlenariaPresenca(models.Model): ordering = ['parlamentar__nome_parlamentar'] +@reversion.register() class Bloco(models.Model): ''' * blocos podem existir por mais de uma legislatura diff --git a/sapl/settings.py b/sapl/settings.py index 918b4d2b2..add1f2d72 100644 --- a/sapl/settings.py +++ b/sapl/settings.py @@ -78,7 +78,7 @@ INSTALLED_APPS = ( 'floppyforms', 'sass_processor', 'rest_framework', - + 'reversion', ) + SAPL_APPS From 8f13cf33a22e44be873e336468f95ff69a094cd1 Mon Sep 17 00:00:00 2001 From: Luciano Almeida Date: Wed, 25 Jan 2017 14:27:14 -0200 Subject: [PATCH 02/11] Adiciona django-reversion nos requirements Signed-off-by: Luciano Almeida --- requirements/requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements/requirements.txt b/requirements/requirements.txt index c6e9f2266..36ed3844b 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -28,3 +28,4 @@ rtyaml==0.0.3 unipath==1.1 python-magic==0.4.12 gunicorn==19.6.0 +django-reversion==2.0.8 From bc3c46b63d9fd07ac7250d61a1e36c79d907f830 Mon Sep 17 00:00:00 2001 From: Luciano Almeida Date: Thu, 2 Feb 2017 16:11:32 -0200 Subject: [PATCH 03/11] Adiciona reversion no admin Signed-off-by: Luciano Almeida --- sapl/base/admin.py | 14 ++++++++++++++ sapl/settings.py | 1 + sapl/utils.py | 5 ++++- 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/sapl/base/admin.py b/sapl/base/admin.py index 02ccd3c60..832b073db 100644 --- a/sapl/base/admin.py +++ b/sapl/base/admin.py @@ -1,6 +1,8 @@ from django.contrib import admin from django.core.urlresolvers import reverse +from django.shortcuts import redirect +from reversion.models import Revision from sapl.base.models import ProblemaMigracao from sapl.utils import register_all_models_in_admin @@ -27,3 +29,15 @@ class ProblemaMigracaoAdmin(admin.ModelAdmin): get_url.short_description = "Endereço" get_url.allow_tags = True + + +class RevisionAdmin(admin.ModelAdmin): + list_display = ('user', 'comment', 'date_created') + search_fields = ('=user__username', '=user__email') + date_hierarchy = ('date_created') + + def change_view(self, request, obj=None): + self.message_user(request, 'You cannot change history.') + return redirect('admin:reversion_revision_changelist') + +admin.site.register(Revision, RevisionAdmin) diff --git a/sapl/settings.py b/sapl/settings.py index add1f2d72..37646e675 100644 --- a/sapl/settings.py +++ b/sapl/settings.py @@ -86,6 +86,7 @@ if DEBUG: INSTALLED_APPS += ('debug_toolbar', 'rest_framework_docs',) MIDDLEWARE_CLASSES = ( + 'reversion.middleware.RevisionMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.locale.LocaleMiddleware', 'django.middleware.common.CommonMiddleware', diff --git a/sapl/utils.py b/sapl/utils.py index bda144e5d..28c48d413 100644 --- a/sapl/utils.py +++ b/sapl/utils.py @@ -18,6 +18,9 @@ from django.contrib.contenttypes.fields import (GenericForeignKey, GenericRel, from django.core.exceptions import ValidationError from django.utils.translation import ugettext_lazy as _ from floppyforms import ClearableFileInput +from reversion.admin import VersionAdmin +import django_filters +import magic from sapl.crispy_layout_mixin import SaplFormLayout, form_actions, to_row from sapl.settings import BASE_DIR @@ -195,7 +198,7 @@ def register_all_models_in_admin(module_name): appname = appname[1] if appname[0] == 'sapl' else appname[0] app = apps.get_app_config(appname) for model in app.get_models(): - class CustomModelAdmin(admin.ModelAdmin): + class CustomModelAdmin(VersionAdmin): list_display = [f.name for f in model._meta.fields if f.name != 'id'] From a36f3bf5ef43afac2031dc71a0097bcb38c845b2 Mon Sep 17 00:00:00 2001 From: Luciano Almeida Date: Thu, 2 Feb 2017 16:13:48 -0200 Subject: [PATCH 04/11] =?UTF-8?q?Migra=20VinculoNormaJuridica=20e=20revers?= =?UTF-8?q?ion=20em=20exclus=C3=A3o?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Luciano Almeida --- sapl/legacy/migration.py | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/sapl/legacy/migration.py b/sapl/legacy/migration.py index 40741412b..10bcedda6 100644 --- a/sapl/legacy/migration.py +++ b/sapl/legacy/migration.py @@ -21,7 +21,8 @@ from sapl.legacy.models import Protocolo as ProtocoloLegado from sapl.materia.models import (Proposicao, StatusTramitacao, TipoDocumento, TipoMateriaLegislativa, TipoProposicao, Tramitacao) -from sapl.norma.models import AssuntoNorma, NormaJuridica +from sapl.legacy.models import Protocolo as ProtocoloLegado +from sapl.norma.models import AssuntoNorma, NormaJuridica, VinculoNormaJuridica from sapl.parlamentares.models import Parlamentar from sapl.protocoloadm.models import Protocolo, StatusTramitacaoAdministrativo from sapl.sessao.models import ExpedienteMateria, OrdemDia, SessaoPlenaria @@ -285,6 +286,25 @@ def get_fields_dict(model): return fields_dict +def fill_vinculo_norma_juridica(): + lista = [('A', 'Altera a norma'), + ('R', 'Revoga integralmente a norma'), + ('P', 'Revoga parcialmente a norma'), + ('T', 'Revoga integralmente por consolidação'), + ('C', 'Norma Correlata'), + ('S', 'Ressalva a Norma'), + ('E', 'Reedita a Norma'), + ('I', 'Reedita a Norma com Alteração'), + ('G', 'Regulamenta a Norma'), + ('K', 'Suspende parcialmente a norma'), + ('L', 'Suspende integralmente a norma'), + ('N', 'Julgada integralmente inconstitucional'), + ('O', 'Julgada parcialmente inconstitucional')] + lista_objs = [VinculoNormaJuridica(sigla=item[0], descricao=item[1]) + for item in lista] + VinculoNormaJuridica.objects.bulk_create(lista_objs) + + class DataMigrator: def __init__(self): @@ -363,6 +383,7 @@ class DataMigrator: self.to_delete = [] Revision.objects.all().delete() Version.objects.all().delete() + VinculoNormaJuridica.objects.all().delete() ProblemaMigracao.objects.all().delete() exec_sql_file('sapl/legacy/scripts/fix_tables.sql', 'legacy') get_user_model().objects.exclude(is_superuser=True).delete() @@ -390,8 +411,10 @@ class DataMigrator: reversion.set_comment('Objeto excluído pela migração') info('Deletando stubs desnecessários...') - while self.delete_stubs(): - pass + with reversion.create_revision(): + while self.delete_stubs(): + pass + reversion.set_comment('Stub desnecessário excluido') info('Recriando unique constraints...') # recreate_constraints() From 3be17d2cdfd86eb9ac69ffdbbfcfa8dfa4a6d0ff Mon Sep 17 00:00:00 2001 From: Luciano Almeida Date: Thu, 2 Feb 2017 16:16:16 -0200 Subject: [PATCH 05/11] Cria log do reversion quando objeto for deletado Signed-off-by: Luciano Almeida --- sapl/rules/apps.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/sapl/rules/apps.py b/sapl/rules/apps.py index b6982b587..be77bb449 100644 --- a/sapl/rules/apps.py +++ b/sapl/rules/apps.py @@ -10,6 +10,10 @@ from django.db import models, router from django.db.utils import DEFAULT_DB_ALIAS from django.utils.translation import ugettext_lazy as _ from django.utils.translation import string_concat +import django +from django.dispatch import receiver +from django.db.models.signals import pre_delete +import reversion from sapl.rules import (SAPL_GROUP_ADMINISTRATIVO, SAPL_GROUP_COMISSOES, SAPL_GROUP_GERAL, SAPL_GROUP_MATERIA, SAPL_GROUP_NORMA, @@ -233,3 +237,11 @@ models.signals.post_migrate.connect( models.signals.post_migrate.connect( receiver=create_proxy_permissions, dispatch_uid="django.contrib.auth.management.create_permissions") + + +@receiver(pre_delete) +def revision_pre_delete_signal(sender, **kwargs): + if sender.__name__ not in ['Version', 'Revision']: + with reversion.create_revision(): + kwargs['instance'].save() + reversion.set_comment("Deletado.") From bffcdde4f93fd51769f776a63083728a90d5fb15 Mon Sep 17 00:00:00 2001 From: Luciano Almeida Date: Wed, 22 Feb 2017 15:45:28 -0300 Subject: [PATCH 06/11] =?UTF-8?q?Context=20Manager=20para=20desligar=20sin?= =?UTF-8?q?al=20quando=20necess=C3=A1rio?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Luciano Almeida --- sapl/context_processors.py | 2 - sapl/legacy/migration.py | 108 +++++++++++++++++++++++++------------ sapl/rules/apps.py | 18 +++---- 3 files changed, 83 insertions(+), 45 deletions(-) diff --git a/sapl/context_processors.py b/sapl/context_processors.py index cc7daca57..2386c0338 100644 --- a/sapl/context_processors.py +++ b/sapl/context_processors.py @@ -1,5 +1,3 @@ - - from sapl.base.views import get_casalegislativa diff --git a/sapl/legacy/migration.py b/sapl/legacy/migration.py index 10bcedda6..e0ba0c679 100644 --- a/sapl/legacy/migration.py +++ b/sapl/legacy/migration.py @@ -1,14 +1,15 @@ import re from datetime import date +from subprocess import call, PIPE import pkg_resources import yaml from django.apps import apps from django.apps.config import AppConfig from django.contrib.auth import get_user_model from django.core.exceptions import ObjectDoesNotExist -from django.db import OperationalError, ProgrammingError, connections, models -from django.db.models import CharField, Max, ProtectedError, TextField +from django.db import connections, models, OperationalError, ProgrammingError +from django.db.models import CharField, TextField, ProtectedError, Max, signals from django.db.models.base import ModelBase from model_mommy import mommy from model_mommy.mommy import foreign_key_required, make @@ -26,6 +27,7 @@ from sapl.norma.models import AssuntoNorma, NormaJuridica, VinculoNormaJuridica from sapl.parlamentares.models import Parlamentar from sapl.protocoloadm.models import Protocolo, StatusTramitacaoAdministrativo from sapl.sessao.models import ExpedienteMateria, OrdemDia, SessaoPlenaria +from sapl.rules.apps import revision_pre_delete_signal from sapl.utils import normalize # BASE ###################################################################### @@ -381,12 +383,17 @@ class DataMigrator: def migrate(self, obj=appconfs): # warning: model/app migration order is of utmost importance self.to_delete = [] - Revision.objects.all().delete() - Version.objects.all().delete() - VinculoNormaJuridica.objects.all().delete() - ProblemaMigracao.objects.all().delete() exec_sql_file('sapl/legacy/scripts/fix_tables.sql', 'legacy') - get_user_model().objects.exclude(is_superuser=True).delete() + with desconecta_revisao_delete( + signal=signals.pre_delete, + receiver=revision_pre_delete_signal, + senders=[VinculoNormaJuridica, + ProblemaMigracao, get_user_model()]): + VinculoNormaJuridica.objects.all().delete() + ProblemaMigracao.objects.all().delete() + get_user_model().objects.exclude(is_superuser=True).delete() + Revision.objects.all().delete() + Version.objects.all().delete() info('Começando migração: %s...' % obj) self._do_migrate(obj) @@ -395,26 +402,19 @@ class DataMigrator: while self.to_delete: for obj in self.to_delete: try: - with reversion.create_revision(): - obj.delete() - self.to_delete.remove(obj) - reversion.set_comment( - 'Objeto com ind_excluido deletado') + obj.delete() + self.to_delete.remove(obj) except ProtectedError: - with reversion.create_revision(): - msg = 'A entrada de PK %s da model %s não pode ser ' \ - 'excluida' % (obj.pk, obj._meta.model_name) - descricao = 'Um ou mais objetos protegidos ' - warn(msg + ' => ' + descricao) - save_relation(obj=obj, problema=msg, - descricao=descricao, eh_stub=False) - reversion.set_comment('Objeto excluído pela migração') + msg = 'A entrada de PK %s da model %s não pode ser ' \ + 'excluida' % (obj.pk, obj._meta.model_name) + descricao = 'Um ou mais objetos protegidos ' + warn(msg + ' => ' + descricao) + save_relation(obj=obj, problema=msg, + descricao=descricao, eh_stub=False) info('Deletando stubs desnecessários...') - with reversion.create_revision(): - while self.delete_stubs(): - pass - reversion.set_comment('Stub desnecessário excluido') + while self.delete_stubs(): + pass info('Recriando unique constraints...') # recreate_constraints() @@ -448,8 +448,16 @@ class DataMigrator: # Clear all model entries # They may have been created in a previous migration attempt try: + # with desconecta_revisao_delete( + # signal=signals.pre_delete, + # receiver=revision_pre_delete_signal, + # senders=[model]): model.objects.all().delete() except ProtectedError: + # with desconecta_revisao_delete( + # signal=signals.pre_delete, + # receiver=revision_pre_delete_signal, + # senders=[model, Proposicao]): Proposicao.objects.all().delete() model.objects.all().delete() delete_constraints(model) @@ -498,17 +506,13 @@ class DataMigrator: original = obj.content_type.get_all_objects_for_this_type( id=obj.object_id) if stub_desnecessario(original[0]): - with reversion.create_revision(): - qtd_exclusoes, *_ = original.delete() - assert qtd_exclusoes == 1 - qtd_exclusoes, *_ = obj.delete() - assert qtd_exclusoes == 1 - excluidos = excluidos + 1 - reversion.set_comment('Stub desnecessario excluido') - elif not obj.content_object and not obj.eh_stub: - with reversion.create_revision(): + qtd_exclusoes, *_ = original.delete() + assert qtd_exclusoes == 1 qtd_exclusoes, *_ = obj.delete() - reversion.set_comment('Stub desnecessário excluido') + assert qtd_exclusoes == 1 + excluidos = excluidos + 1 + elif not obj.content_object and not obj.eh_stub: + qtd_exclusoes, *_ = obj.delete() assert qtd_exclusoes == 1 excluidos = excluidos + 1 return excluidos @@ -710,3 +714,39 @@ def make_with_log(model, _quantity=None, make_m2m=False, **attrs): return stub make_with_log.required = foreign_key_required + +# DISCONNECT SIGNAL TO DELETE ################################################ + + +class desconecta_revisao_delete(): + def __init__(self, signal, receiver, senders=[], dispatch_uid=None): + self.signal = signal + self.receiver = receiver + self.senders = senders + self.dispatch_uid = dispatch_uid + + def disconnect_signal(self, model): + self.signal.disconnect( + receiver=self.receiver, + sender=model, + dispatch_uid=self.dispatch_uid, + weak=False,) + + def connect_signal(self, model): + self.signal.connect( + receiver=self.receiver, + sender=model, + dispatch_uid=self.dispatch_uid, + weak=False,) + + def __enter__(self): + for sender in self.senders: + self.disconnect_signal(sender) + for related in sender._meta.get_all_related_objects_with_model(): + self.disconnect_signal(related[0].related_model) + + def __exit__(self, type, value, traceback): + for sender in self.senders: + self.connect_signal(sender) + for related in sender._meta.get_all_related_objects_with_model(): + self.connect_signal(related[0].related_model) diff --git a/sapl/rules/apps.py b/sapl/rules/apps.py index be77bb449..e9bf2c50e 100644 --- a/sapl/rules/apps.py +++ b/sapl/rules/apps.py @@ -11,8 +11,6 @@ from django.db.utils import DEFAULT_DB_ALIAS from django.utils.translation import ugettext_lazy as _ from django.utils.translation import string_concat import django -from django.dispatch import receiver -from django.db.models.signals import pre_delete import reversion from sapl.rules import (SAPL_GROUP_ADMINISTRATIVO, SAPL_GROUP_COMISSOES, @@ -230,6 +228,12 @@ def update_groups(app_config, verbosity=2, interactive=True, rules.update_groups() +def revision_pre_delete_signal(sender, **kwargs): + with reversion.create_revision(): + kwargs['instance'].save() + reversion.set_comment("Deletado pelo sinal.") + + models.signals.post_migrate.connect( receiver=update_groups) @@ -238,10 +242,6 @@ models.signals.post_migrate.connect( receiver=create_proxy_permissions, dispatch_uid="django.contrib.auth.management.create_permissions") - -@receiver(pre_delete) -def revision_pre_delete_signal(sender, **kwargs): - if sender.__name__ not in ['Version', 'Revision']: - with reversion.create_revision(): - kwargs['instance'].save() - reversion.set_comment("Deletado.") +models.signals.pre_delete.connect( + receiver=revision_pre_delete_signal, + dispatch_uid="pre_delete_signal") From ef47214c86b1b943da76a4afc417db258ee633f2 Mon Sep 17 00:00:00 2001 From: Luciano Almeida Date: Fri, 24 Feb 2017 11:13:09 -0300 Subject: [PATCH 07/11] =?UTF-8?q?Muda=20jeito=20de=20exclus=C3=A3o=20inici?= =?UTF-8?q?al=20do=20banco?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Luciano Almeida --- sapl/legacy/migration.py | 63 ++++++++++------------------------------ 1 file changed, 15 insertions(+), 48 deletions(-) diff --git a/sapl/legacy/migration.py b/sapl/legacy/migration.py index e0ba0c679..1228252e9 100644 --- a/sapl/legacy/migration.py +++ b/sapl/legacy/migration.py @@ -27,7 +27,6 @@ from sapl.norma.models import AssuntoNorma, NormaJuridica, VinculoNormaJuridica from sapl.parlamentares.models import Parlamentar from sapl.protocoloadm.models import Protocolo, StatusTramitacaoAdministrativo from sapl.sessao.models import ExpedienteMateria, OrdemDia, SessaoPlenaria -from sapl.rules.apps import revision_pre_delete_signal from sapl.utils import normalize # BASE ###################################################################### @@ -382,18 +381,22 @@ class DataMigrator: def migrate(self, obj=appconfs): # warning: model/app migration order is of utmost importance - self.to_delete = [] exec_sql_file('sapl/legacy/scripts/fix_tables.sql', 'legacy') - with desconecta_revisao_delete( - signal=signals.pre_delete, - receiver=revision_pre_delete_signal, - senders=[VinculoNormaJuridica, - ProblemaMigracao, get_user_model()]): - VinculoNormaJuridica.objects.all().delete() - ProblemaMigracao.objects.all().delete() - get_user_model().objects.exclude(is_superuser=True).delete() - Revision.objects.all().delete() - Version.objects.all().delete() + self.to_delete = [] + + # excluindo database antigo. + info('Todos os dados do banco serão excluidos. ' + 'Recomendamos que faça backup do banco sapl antes de continuar.') + info('Deseja continuar? [s/n]') + resposta = input() + if resposta.lower() in ['s', 'sim', 'y', 'yes']: + pass + else: + info('Migração cancelada.') + return 0 + info('Excluindo entradas antigas do banco.') + call(['./manage.py', 'flush', '--settings=sapl.settings', + '--database=default', '--no-input'], stdout=PIPE) info('Começando migração: %s...' % obj) self._do_migrate(obj) @@ -714,39 +717,3 @@ def make_with_log(model, _quantity=None, make_m2m=False, **attrs): return stub make_with_log.required = foreign_key_required - -# DISCONNECT SIGNAL TO DELETE ################################################ - - -class desconecta_revisao_delete(): - def __init__(self, signal, receiver, senders=[], dispatch_uid=None): - self.signal = signal - self.receiver = receiver - self.senders = senders - self.dispatch_uid = dispatch_uid - - def disconnect_signal(self, model): - self.signal.disconnect( - receiver=self.receiver, - sender=model, - dispatch_uid=self.dispatch_uid, - weak=False,) - - def connect_signal(self, model): - self.signal.connect( - receiver=self.receiver, - sender=model, - dispatch_uid=self.dispatch_uid, - weak=False,) - - def __enter__(self): - for sender in self.senders: - self.disconnect_signal(sender) - for related in sender._meta.get_all_related_objects_with_model(): - self.disconnect_signal(related[0].related_model) - - def __exit__(self, type, value, traceback): - for sender in self.senders: - self.connect_signal(sender) - for related in sender._meta.get_all_related_objects_with_model(): - self.connect_signal(related[0].related_model) From 6e285d8e33c01b68565738fb4456c2caf9149bc3 Mon Sep 17 00:00:00 2001 From: Luciano Almeida Date: Fri, 3 Mar 2017 16:11:05 -0300 Subject: [PATCH 08/11] Arruma model renomeada e diff do rebase Signed-off-by: Luciano Almeida --- sapl/legacy/migration.py | 3 ++- sapl/norma/legacy.yaml | 9 +++++---- sapl/sessao/models.py | 5 ----- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/sapl/legacy/migration.py b/sapl/legacy/migration.py index 1228252e9..82a14e70e 100644 --- a/sapl/legacy/migration.py +++ b/sapl/legacy/migration.py @@ -23,7 +23,8 @@ from sapl.materia.models import (Proposicao, StatusTramitacao, TipoDocumento, TipoMateriaLegislativa, TipoProposicao, Tramitacao) from sapl.legacy.models import Protocolo as ProtocoloLegado -from sapl.norma.models import AssuntoNorma, NormaJuridica, VinculoNormaJuridica +from sapl.norma.models import (AssuntoNorma, NormaJuridica, + TipoVinculoNormaJuridica) from sapl.parlamentares.models import Parlamentar from sapl.protocoloadm.models import Protocolo, StatusTramitacaoAdministrativo from sapl.sessao.models import ExpedienteMateria, OrdemDia, SessaoPlenaria diff --git a/sapl/norma/legacy.yaml b/sapl/norma/legacy.yaml index 89038ef69..17a7f083d 100644 --- a/sapl/norma/legacy.yaml +++ b/sapl/norma/legacy.yaml @@ -42,7 +42,8 @@ LegislacaoCitada: subsecao: des_subsecao titulo: des_titulo -VinculoNormaJuridica: - norma_referente: cod_norma_referente - norma_referida: cod_norma_referida - tipo_vinculo: tip_vinculo +# TODO Descomentar quando a issue #832 for concluida +# TipoVinculoNormaJuridica (VinculoNormaJuridica): +# norma_referente: cod_norma_referente +# norma_referida: cod_norma_referida +# tipo_vinculo: tip_vinculo diff --git a/sapl/sessao/models.py b/sapl/sessao/models.py index aab0e3850..e76f6392f 100644 --- a/sapl/sessao/models.py +++ b/sapl/sessao/models.py @@ -177,13 +177,8 @@ class SessaoPlenaria(models.Model): def save(self, force_insert=False, force_update=False, using=None, update_fields=None): -<<<<<<< 0d281b8f594224dfa3ede0c7e6ccb32395bdfe42 - if not self.pk and (self.upload_pauta or - self.upload_ata or self.upload_anexo): -======= if not self.pk and (self.upload_pauta or self.upload_ata or self.upload_anexo): ->>>>>>> Migra usando django-reversion upload_pauta = self.upload_pauta upload_ata = self.upload_ata upload_anexo = self.upload_anexo From e31972658a2d8d9d77f38268ae5901a461200372 Mon Sep 17 00:00:00 2001 From: Luciano Almeida Date: Fri, 3 Mar 2017 16:35:22 -0300 Subject: [PATCH 09/11] Cria makemigrations --merge Signed-off-by: Luciano Almeida --- sapl/materia/migrations/0076_merge.py | 16 ++++++++++++++++ sapl/norma/migrations/0036_merge.py | 16 ++++++++++++++++ sapl/protocoloadm/migrations/0011_merge.py | 16 ++++++++++++++++ 3 files changed, 48 insertions(+) create mode 100644 sapl/materia/migrations/0076_merge.py create mode 100644 sapl/norma/migrations/0036_merge.py create mode 100644 sapl/protocoloadm/migrations/0011_merge.py diff --git a/sapl/materia/migrations/0076_merge.py b/sapl/materia/migrations/0076_merge.py new file mode 100644 index 000000000..49ae8f130 --- /dev/null +++ b/sapl/materia/migrations/0076_merge.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.7 on 2017-03-03 16:34 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('materia', '0075_auto_20170203_1019'), + ('materia', '0075_auto_20170123_1548'), + ] + + operations = [ + ] diff --git a/sapl/norma/migrations/0036_merge.py b/sapl/norma/migrations/0036_merge.py new file mode 100644 index 000000000..207c3b3c0 --- /dev/null +++ b/sapl/norma/migrations/0036_merge.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.7 on 2017-03-03 16:34 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('norma', '0035_auto_20170222_1438'), + ('norma', '0033_auto_20170123_1548'), + ] + + operations = [ + ] diff --git a/sapl/protocoloadm/migrations/0011_merge.py b/sapl/protocoloadm/migrations/0011_merge.py new file mode 100644 index 000000000..10ea183c3 --- /dev/null +++ b/sapl/protocoloadm/migrations/0011_merge.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.7 on 2017-03-03 16:34 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('protocoloadm', '0010_auto_20170203_1019'), + ('protocoloadm', '0010_auto_20170123_1548'), + ] + + operations = [ + ] From b6e4a9f66208fca2d0834ac554bcaec0edec42a3 Mon Sep 17 00:00:00 2001 From: Marcio Mazza Date: Wed, 8 Mar 2017 09:16:31 -0300 Subject: [PATCH 10/11] Internacionaliza string --- sapl/base/admin.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sapl/base/admin.py b/sapl/base/admin.py index 832b073db..941faf8d1 100644 --- a/sapl/base/admin.py +++ b/sapl/base/admin.py @@ -1,8 +1,9 @@ from django.contrib import admin from django.core.urlresolvers import reverse from django.shortcuts import redirect - +from django.utils.translation import ugettext_lazy as _ from reversion.models import Revision + from sapl.base.models import ProblemaMigracao from sapl.utils import register_all_models_in_admin @@ -37,7 +38,7 @@ class RevisionAdmin(admin.ModelAdmin): date_hierarchy = ('date_created') def change_view(self, request, obj=None): - self.message_user(request, 'You cannot change history.') + self.message_user(request, _('You cannot change history.')) return redirect('admin:reversion_revision_changelist') admin.site.register(Revision, RevisionAdmin) From 35dc30494d03f2614a831f0d92ce76c817c715bf Mon Sep 17 00:00:00 2001 From: Luciano Almeida Date: Fri, 10 Mar 2017 11:59:37 -0300 Subject: [PATCH 11/11] Arruma TipoProposicao inexistente Signed-off-by: Luciano Almeida --- sapl/legacy/migration.py | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/sapl/legacy/migration.py b/sapl/legacy/migration.py index 82a14e70e..626aed4ee 100644 --- a/sapl/legacy/migration.py +++ b/sapl/legacy/migration.py @@ -7,6 +7,7 @@ import yaml from django.apps import apps from django.apps.config import AppConfig from django.contrib.auth import get_user_model +from django.contrib.contenttypes.models import ContentType from django.core.exceptions import ObjectDoesNotExist from django.db import connections, models, OperationalError, ProgrammingError from django.db.models import CharField, TextField, ProtectedError, Max, signals @@ -142,13 +143,27 @@ def get_fk_related(field, value, label=None): if field.model._meta.label == 'sessao.RegistroVotacao' and \ field.name == 'ordem': return value - with reversion.create_revision(): - reversion.set_comment('Stub criado pela migração') - value = make_stub(field.related_model, value) - descricao = 'stub criado para entrada orfã!' - warn(msg + ' => ' + descricao) - save_relation(value, [field.name], msg, descricao, - eh_stub=True) + # Caso TipoProposicao não exista, um objeto será criado então + # com content_type=13 (ProblemaMigracao) + if field.related_model.__name__ == 'TipoProposicao': + tipo = TipoProposicao.objects.filter(descricao='Erro') + if not tipo: + with reversion.create_revision(): + reversion.set_comment( + 'TipoProposicao "Erro" criado') + ct = ContentType.objects.get(pk=13) + value = TipoProposicao.objects.create( + id=value, descricao='Erro', content_type=ct) + else: + value = tipo[0] + else: + with reversion.create_revision(): + reversion.set_comment('Stub criado pela migração') + value = make_stub(field.related_model, value) + descricao = 'stub criado para entrada orfã!' + warn(msg + ' => ' + descricao) + save_relation(value, [field.name], msg, descricao, + eh_stub=True) else: assert value return value @@ -452,16 +467,8 @@ class DataMigrator: # Clear all model entries # They may have been created in a previous migration attempt try: - # with desconecta_revisao_delete( - # signal=signals.pre_delete, - # receiver=revision_pre_delete_signal, - # senders=[model]): model.objects.all().delete() except ProtectedError: - # with desconecta_revisao_delete( - # signal=signals.pre_delete, - # receiver=revision_pre_delete_signal, - # senders=[model, Proposicao]): Proposicao.objects.all().delete() model.objects.all().delete() delete_constraints(model)