Browse Source

Migra app Contatos

revisaoSidenav
Sesostris Vieira 3 years ago
parent
commit
9907b24457
  1. 55
      sigi/apps/contatos/admin.py
  2. 6
      sigi/apps/contatos/apps.py
  3. 46
      sigi/apps/contatos/filters.py
  4. 13
      sigi/apps/contatos/migrations/0001_initial.py
  5. 6
      sigi/apps/contatos/migrations/0002_auto_20151104_0810.py
  6. 133
      sigi/apps/contatos/migrations/0005_alter_mesorregiao_options_alter_microrregiao_options_and_more.py
  7. 153
      sigi/apps/contatos/models.py
  8. 3
      sigi/apps/contatos/tests.py
  9. 2
      sigi/apps/utils/__init__.py
  10. 1
      sigi/apps/utils/base_admin.py
  11. 97
      sigi/apps/utils/filters.py
  12. 1
      sigi/settings/base.py

55
sigi/apps/contatos/admin.py

@ -1,12 +1,12 @@
# -*- coding: utf-8 -*-
from django.contrib import admin from django.contrib import admin
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from sigi.apps.contatos.filters import PopulationFilter from sigi.apps.utils.filters import RangeFilter
from sigi.apps.contatos.models import (UnidadeFederativa, Mesorregiao, Microrregiao, from sigi.apps.contatos.models import (UnidadeFederativa, Mesorregiao,
Municipio, Telefone, Contato) Microrregiao, Municipio, Telefone,
Contato)
from sigi.apps.utils import queryset_ascii from sigi.apps.utils import queryset_ascii
from sigi.apps.utils.base_admin import BaseModelAdmin
class MesorregiaoInline(admin.TabularInline): class MesorregiaoInline(admin.TabularInline):
model = Mesorregiao model = Mesorregiao
@ -14,35 +14,43 @@ class MesorregiaoInline(admin.TabularInline):
class MicrorregiaoInline(admin.TabularInline): class MicrorregiaoInline(admin.TabularInline):
model = Microrregiao model = Microrregiao
class UnidadeFederativaAdmin(BaseModelAdmin): @admin.register(UnidadeFederativa)
class UnidadeFederativaAdmin(admin.ModelAdmin):
actions = None actions = None
list_display = ('codigo_ibge', 'nome', 'sigla', 'regiao', 'populacao') list_display = ('codigo_ibge', 'nome', 'sigla', 'regiao', 'populacao')
list_display_links = ('codigo_ibge', 'nome') list_display_links = ('codigo_ibge', 'nome')
list_filter = ('regiao', 'populacao', PopulationFilter,) list_filter = ('regiao', ('populacao', RangeFilter),)
search_fields = ('search_text', 'codigo_ibge', 'sigla', 'regiao') search_fields = ('search_text', 'codigo_ibge', 'sigla', 'regiao')
get_queryset = queryset_ascii get_queryset = queryset_ascii
inlines = (MesorregiaoInline, ) inlines = (MesorregiaoInline, )
class MesorregiaoAdmin(BaseModelAdmin): @admin.register(Mesorregiao)
class MesorregiaoAdmin(admin.ModelAdmin):
actions = None actions = None
list_display = ('codigo_ibge', 'uf', 'nome') list_display = ('codigo_ibge', 'uf', 'nome')
list_display_links = ('codigo_ibge', 'nome') list_display_links = ('codigo_ibge', 'nome')
list_filter = ('uf',) list_filter = ('uf',)
search_fields = ('uf__search_text', 'search_text', 'codigo_ibge', 'uf__sigla') search_fields = ('uf__search_text', 'search_text', 'codigo_ibge',
'uf__sigla')
get_queryset = queryset_ascii get_queryset = queryset_ascii
inlines = (MicrorregiaoInline,) inlines = (MicrorregiaoInline,)
class MunicipioAdmin(BaseModelAdmin): @admin.register(Municipio)
class MunicipioAdmin(admin.ModelAdmin):
actions = None actions = None
list_display = ('codigo_ibge', 'codigo_tse', 'nome', 'uf', 'is_capital', 'populacao', 'is_polo', 'idh', 'pib_ano', list_display = ('codigo_ibge', 'codigo_tse', 'nome', 'uf', 'is_capital',
'pib_total', 'pib_percapita') 'populacao', 'is_polo', 'idh', 'pib_ano', 'pib_total',
'pib_percapita')
list_display_links = ('codigo_ibge', 'codigo_tse', 'nome') list_display_links = ('codigo_ibge', 'codigo_tse', 'nome')
list_filter = ('is_capital', 'is_polo', 'idh', 'populacao', 'uf', ) list_filter = ('is_capital', 'is_polo', ('idh', RangeFilter),
('populacao', RangeFilter), 'uf__regiao', 'uf', )
get_queryset = queryset_ascii get_queryset = queryset_ascii
fieldsets = ( fieldsets = (
(None, { (None, {
'fields': ('codigo_ibge', 'codigo_tse', 'nome', 'data_criacao', 'uf', 'microrregiao', 'fields': ('codigo_ibge', 'codigo_tse', 'nome', 'data_criacao',
'is_capital', 'populacao', 'is_polo', 'idh', 'pib_ano', 'pib_total', 'pib_percapita') 'uf', 'microrregiao', 'is_capital', 'populacao',
'is_polo', 'idh', 'pib_ano', 'pib_total',
'pib_percapita')
}), }),
(_('Posição geográfica'), { (_('Posição geográfica'), {
'fields': ('latitude', 'longitude'), 'fields': ('latitude', 'longitude'),
@ -50,23 +58,18 @@ class MunicipioAdmin(BaseModelAdmin):
) )
search_fields = ('search_text', 'codigo_ibge', 'codigo_tse', 'uf__sigla') search_fields = ('search_text', 'codigo_ibge', 'codigo_tse', 'uf__sigla')
@admin.register(Telefone)
class TelefoneAdmin(BaseModelAdmin): class TelefoneAdmin(admin.ModelAdmin):
list_display = ('numero', 'tipo', 'nota') list_display = ('numero', 'tipo', 'nota')
list_display_links = ('numero',) list_display_links = ('numero',)
list_filter = ('tipo',) list_filter = ('tipo',)
radio_fields = {'tipo': admin.VERTICAL} radio_fields = {'tipo': admin.VERTICAL}
search_fields = ('numero', 'tipo', 'nota') search_fields = ('numero', 'tipo', 'nota')
@admin.register(Contato)
class ContatoAdmin(BaseModelAdmin): class ContatoAdmin(admin.ModelAdmin):
list_display = ('nome', 'nota', 'email', 'municipio') list_display = ('nome', 'nota', 'email', 'municipio')
list_display_links = ('nome',) list_display_links = ('nome',)
list_filter = ('nome',) list_filter = ('nome',)
search_fields = ('nome', 'nota', 'email', 'municipio__nome', 'municipio__uf__nome') search_fields = ('nome', 'nota', 'email', 'municipio__nome',
'municipio__uf__nome')
admin.site.register(UnidadeFederativa, UnidadeFederativaAdmin)
admin.site.register(Mesorregiao, MesorregiaoAdmin)
admin.site.register(Municipio, MunicipioAdmin)
admin.site.register(Telefone, TelefoneAdmin)
admin.site.register(Contato, ContatoAdmin)

6
sigi/apps/contatos/apps.py

@ -0,0 +1,6 @@
from django.apps import AppConfig
from django.utils.translation import gettext_lazy as _
class ContatosConfig(AppConfig):
name = 'sigi.apps.contatos'
verbose_name = _('contatos')

46
sigi/apps/contatos/filters.py

@ -1,46 +0,0 @@
# coding: utf-8
from django.contrib import admin
from django.utils.translation import gettext as _
class PopulationFilter(admin.SimpleListFilter):
# Human-readable title which will be displayed in the
# right admin sidebar just above the filter options.
title = _('População')
# Parameter for the filter that will be used in the URL query.
parameter_name = 'faixa'
def lookups(self, request, model_admin):
"""
Returns a list of tuples. The first element in each
tuple is the coded value for the option that will
appear in the URL query. The second element is the
human-readable name for the option that will appear
in the right sidebar.
"""
return (
('1', _('< 100 Mil')),
('2', _('100 Mil a 1 Milhão')),
('3', _('1 Milhão a 100 Milhões')),
('4', _('> 100 Milhões')),
)
def queryset(self, request, queryset):
"""
Returns the filtered queryset based on the value
provided in the query string and retrievable via
`self.value()`.
"""
# Compare the requested value (either '1', '2', '3' or '4')
# to decide how to filter the queryset.
if self.value() == '1':
return queryset.filter(populacao__lt=100000)
elif self.value() == '2':
return queryset.filter(populacao__gte=100000, populacao__lt=1000000)
elif self.value() == '3':
return queryset.filter(populacao__gte=1000000, populacao__lt=10000000)
elif self.value() == '4':
return queryset.filter(populacao__gt=100000000)
else:
return queryset

13
sigi/apps/contatos/migrations/0001_initial.py

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals from __future__ import unicode_literals
from django.db import models, migrations from django.db import models, migrations
@ -21,7 +20,7 @@ class Migration(migrations.Migration):
('nota', models.CharField(max_length=70, blank=True)), ('nota', models.CharField(max_length=70, blank=True)),
('email', models.EmailField(max_length=75, verbose_name='e-mail', blank=True)), ('email', models.EmailField(max_length=75, verbose_name='e-mail', blank=True)),
('object_id', models.PositiveIntegerField()), ('object_id', models.PositiveIntegerField()),
('content_type', models.ForeignKey(to='contenttypes.ContentType')), ('content_type', models.ForeignKey(to='contenttypes.ContentType', on_delete=models.CASCADE)),
], ],
options={ options={
'ordering': ('nome',), 'ordering': ('nome',),
@ -42,7 +41,7 @@ class Migration(migrations.Migration):
('bairro', models.CharField(max_length=100, blank=True)), ('bairro', models.CharField(max_length=100, blank=True)),
('cep', models.CharField(help_text='Formato: <em>XXXXX-XXX</em>.', max_length=9, null=True, verbose_name='CEP', blank=True)), ('cep', models.CharField(help_text='Formato: <em>XXXXX-XXX</em>.', max_length=9, null=True, verbose_name='CEP', blank=True)),
('object_id', models.PositiveIntegerField()), ('object_id', models.PositiveIntegerField()),
('content_type', models.ForeignKey(to='contenttypes.ContentType')), ('content_type', models.ForeignKey(to='contenttypes.ContentType', on_delete=models.CASCADE)),
], ],
options={ options={
'ordering': ('logradouro', 'numero'), 'ordering': ('logradouro', 'numero'),
@ -87,7 +86,7 @@ class Migration(migrations.Migration):
('nota', models.CharField(max_length=70, null=True, blank=True)), ('nota', models.CharField(max_length=70, null=True, blank=True)),
('ult_alteracao', models.DateTimeField(auto_now=True, verbose_name='\xdaltima altera\xe7\xe3o', null=True)), ('ult_alteracao', models.DateTimeField(auto_now=True, verbose_name='\xdaltima altera\xe7\xe3o', null=True)),
('object_id', models.PositiveIntegerField()), ('object_id', models.PositiveIntegerField()),
('content_type', models.ForeignKey(to='contenttypes.ContentType')), ('content_type', models.ForeignKey(to='contenttypes.ContentType', on_delete=models.CASCADE)),
], ],
options={ options={
'ordering': ('numero',), 'ordering': ('numero',),
@ -118,19 +117,19 @@ class Migration(migrations.Migration):
migrations.AddField( migrations.AddField(
model_name='municipio', model_name='municipio',
name='uf', name='uf',
field=models.ForeignKey(verbose_name='UF', to='contatos.UnidadeFederativa'), field=models.ForeignKey(verbose_name='UF', to='contatos.UnidadeFederativa', on_delete=models.CASCADE),
preserve_default=True, preserve_default=True,
), ),
migrations.AddField( migrations.AddField(
model_name='endereco', model_name='endereco',
name='municipio', name='municipio',
field=models.ForeignKey(verbose_name='munic\xedpio', blank=True, to='contatos.Municipio', null=True), field=models.ForeignKey(verbose_name='munic\xedpio', blank=True, to='contatos.Municipio', null=True, on_delete=models.CASCADE),
preserve_default=True, preserve_default=True,
), ),
migrations.AddField( migrations.AddField(
model_name='contato', model_name='contato',
name='municipio', name='municipio',
field=models.ForeignKey(verbose_name='munic\xedpio', blank=True, to='contatos.Municipio', null=True), field=models.ForeignKey(verbose_name='munic\xedpio', blank=True, to='contatos.Municipio', null=True, on_delete=models.CASCADE),
preserve_default=True, preserve_default=True,
), ),
] ]

6
sigi/apps/contatos/migrations/0002_auto_20151104_0810.py

@ -18,7 +18,7 @@ class Migration(migrations.Migration):
('codigo_ibge', models.PositiveIntegerField(help_text='C\xf3digo da mesorregi\xe3o segundo o IBGE', unique=True, serialize=False, verbose_name='C\xf3digo IBGE', primary_key=True)), ('codigo_ibge', models.PositiveIntegerField(help_text='C\xf3digo da mesorregi\xe3o segundo o IBGE', unique=True, serialize=False, verbose_name='C\xf3digo IBGE', primary_key=True)),
('nome', models.CharField(max_length=100, verbose_name='Nome mesorregi\xe3o')), ('nome', models.CharField(max_length=100, verbose_name='Nome mesorregi\xe3o')),
('search_text', sigi.apps.utils.SearchField(field_names=[b'nome'], editable=False)), ('search_text', sigi.apps.utils.SearchField(field_names=[b'nome'], editable=False)),
('uf', models.ForeignKey(verbose_name='UF', to='contatos.UnidadeFederativa')), ('uf', models.ForeignKey(verbose_name='UF', to='contatos.UnidadeFederativa', on_delete=models.CASCADE)),
], ],
options={ options={
'ordering': ('uf', 'nome'), 'ordering': ('uf', 'nome'),
@ -33,7 +33,7 @@ class Migration(migrations.Migration):
('codigo_ibge', models.PositiveIntegerField(help_text='C\xf3digo da microrregi\xe3o segundo o IBGE', unique=True, serialize=False, verbose_name='C\xf3digo IBGE', primary_key=True)), ('codigo_ibge', models.PositiveIntegerField(help_text='C\xf3digo da microrregi\xe3o segundo o IBGE', unique=True, serialize=False, verbose_name='C\xf3digo IBGE', primary_key=True)),
('nome', models.CharField(max_length=100, verbose_name='Nome microrregi\xe3o')), ('nome', models.CharField(max_length=100, verbose_name='Nome microrregi\xe3o')),
('search_text', sigi.apps.utils.SearchField(field_names=[b'nome'], editable=False)), ('search_text', sigi.apps.utils.SearchField(field_names=[b'nome'], editable=False)),
('mesorregiao', models.ForeignKey(to='contatos.Mesorregiao')), ('mesorregiao', models.ForeignKey(to='contatos.Mesorregiao', on_delete=models.CASCADE)),
], ],
options={ options={
'ordering': ('mesorregiao', 'nome'), 'ordering': ('mesorregiao', 'nome'),
@ -53,7 +53,7 @@ class Migration(migrations.Migration):
migrations.AddField( migrations.AddField(
model_name='municipio', model_name='municipio',
name='microrregiao', name='microrregiao',
field=models.ForeignKey(verbose_name='Microrregi\xe3o', blank=True, to='contatos.Microrregiao', null=True), field=models.ForeignKey(verbose_name='Microrregi\xe3o', blank=True, to='contatos.Microrregiao', null=True, on_delete=models.CASCADE),
preserve_default=True, preserve_default=True,
), ),
] ]

133
sigi/apps/contatos/migrations/0005_alter_mesorregiao_options_alter_microrregiao_options_and_more.py

@ -0,0 +1,133 @@
# Generated by Django 4.0.1 on 2022-01-06 23:50
from django.db import migrations, models
import django.db.models.deletion
import sigi.apps.utils
class Migration(migrations.Migration):
dependencies = [
('contatos', '0004_auto_20210611_0946'),
]
operations = [
migrations.AlterModelOptions(
name='mesorregiao',
options={'ordering': ('uf', 'nome'), 'verbose_name': ('mesorregião',), 'verbose_name_plural': 'mesorregiões'},
),
migrations.AlterModelOptions(
name='microrregiao',
options={'ordering': ('nome',), 'verbose_name': 'microrregião', 'verbose_name_plural': 'microrregiões'},
),
migrations.AlterField(
model_name='contato',
name='email',
field=models.EmailField(blank=True, max_length=254, verbose_name='e-mail'),
),
migrations.AlterField(
model_name='contato',
name='id',
field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
),
migrations.AlterField(
model_name='endereco',
name='id',
field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
),
migrations.AlterField(
model_name='endereco',
name='logradouro',
field=models.CharField(max_length=100, verbose_name='logradouro'),
),
migrations.AlterField(
model_name='endereco',
name='tipo',
field=models.CharField(choices=[('aeroporto', 'Aeroporto'), ('alameda', 'Alameda'), ('area', 'Área'), ('avenida', 'Avenida'), ('campo', 'Campo'), ('chacara', 'Chácara'), ('colonia', 'Colônia'), ('condominio', 'Condomínio'), ('conjunto', 'Conjunto'), ('distrito', 'Distrito'), ('esplanada', 'Esplanada'), ('estacao', 'Estação'), ('estrada', 'Estrada'), ('favela', 'Favela'), ('fazenda', 'Fazenda'), ('feira', 'Feira'), ('jardim', 'Jardim'), ('ladeira', 'Ladeira'), ('lago', 'Lago'), ('lagoa', 'Lagoa'), ('largo', 'Largo'), ('loteamento', 'Loteamento'), ('morro', 'Morro'), ('nucleo', 'Núcleo'), ('parque', 'Parque'), ('passarela', 'Passarela'), ('patio', 'Pátio'), ('praca', 'Praça'), ('quadra', 'Quadra'), ('recanto', 'Recanto'), ('residencial', 'Residencial'), ('rodovia', 'Rodovia'), ('rua', 'Rua'), ('setor', 'Setor'), ('sitio', 'Sítio'), ('travessa', 'Travessa'), ('trecho', 'Trecho'), ('trevo', 'Trevo'), ('vale', 'Vale'), ('vereda', 'Vereda'), ('via', 'Via'), ('viaduto', 'Viaduto'), ('viela', 'Viela'), ('vila', 'Vila'), ('outro', 'Outro')], max_length=15, verbose_name='tipo'),
),
migrations.AlterField(
model_name='mesorregiao',
name='codigo_ibge',
field=models.PositiveIntegerField(help_text='Código da mesorregião segundo o IBGE', primary_key=True, serialize=False, unique=True, verbose_name='código IBGE'),
),
migrations.AlterField(
model_name='mesorregiao',
name='nome',
field=models.CharField(max_length=100, verbose_name='nome mesorregião'),
),
migrations.AlterField(
model_name='mesorregiao',
name='search_text',
field=sigi.apps.utils.SearchField(editable=False, field_names=['nome']),
),
migrations.AlterField(
model_name='microrregiao',
name='codigo_ibge',
field=models.PositiveIntegerField(help_text='Código da microrregião segundo o IBGE', primary_key=True, serialize=False, unique=True, verbose_name='código IBGE'),
),
migrations.AlterField(
model_name='microrregiao',
name='mesorregiao',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contatos.mesorregiao', verbose_name='mesorregião'),
),
migrations.AlterField(
model_name='microrregiao',
name='nome',
field=models.CharField(max_length=100, verbose_name='nome microrregião'),
),
migrations.AlterField(
model_name='microrregiao',
name='search_text',
field=sigi.apps.utils.SearchField(editable=False, field_names=['nome']),
),
migrations.AlterField(
model_name='municipio',
name='latitude',
field=models.DecimalField(blank=True, decimal_places=8, help_text='Exemplo: <em>-20,464</em>.', max_digits=10, null=True, verbose_name='latitude'),
),
migrations.AlterField(
model_name='municipio',
name='longitude',
field=models.DecimalField(blank=True, decimal_places=8, help_text='Exemplo: <em>-45,426</em>.', max_digits=11, null=True, verbose_name='longitude'),
),
migrations.AlterField(
model_name='municipio',
name='microrregiao',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='contatos.microrregiao', verbose_name='microrregião'),
),
migrations.AlterField(
model_name='telefone',
name='id',
field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
),
migrations.AlterField(
model_name='telefone',
name='tipo',
field=models.CharField(choices=[('F', 'Fixo'), ('M', 'Móvel'), ('X', 'Fax'), ('I', 'Indefinido')], default='I', max_length=1, verbose_name='tipo'),
),
migrations.AlterField(
model_name='telefone',
name='ult_alteracao',
field=models.DateTimeField(auto_now=True, null=True, verbose_name='última alteração'),
),
migrations.AlterField(
model_name='unidadefederativa',
name='nome',
field=models.CharField(max_length=25, verbose_name='nome UF'),
),
migrations.AlterField(
model_name='unidadefederativa',
name='regiao',
field=models.CharField(choices=[('CO', 'Centro-Oeste'), ('NE', 'Nordeste'), ('NO', 'Norte'), ('SD', 'Sudeste'), ('SL', 'Sul')], max_length=2, verbose_name='região'),
),
migrations.AlterField(
model_name='unidadefederativa',
name='search_text',
field=sigi.apps.utils.SearchField(editable=False, field_names=['nome']),
),
migrations.AlterField(
model_name='unidadefederativa',
name='sigla',
field=models.CharField(help_text='Exemplo: <em>MG</em>.', max_length=2, unique=True, verbose_name='sigla'),
),
]

153
sigi/apps/contatos/models.py

@ -1,18 +1,13 @@
# -*- coding: utf-8 -*-
from django.contrib.contenttypes.fields import (GenericForeignKey, from django.contrib.contenttypes.fields import (GenericForeignKey,
GenericRelation) GenericRelation)
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.core.validators import MaxValueValidator, MinValueValidator from django.core.validators import MaxValueValidator, MinValueValidator
from django.db import models from django.db import models
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from sigi.apps.utils import SearchField from sigi.apps.utils import SearchField
class UnidadeFederativa(models.Model): class UnidadeFederativa(models.Model):
""" Modelo que representa um estado brasileiro
"""
REGIAO_CHOICES = ( REGIAO_CHOICES = (
('CO', _('Centro-Oeste')), ('CO', _('Centro-Oeste')),
('NE', _('Nordeste')), ('NE', _('Nordeste')),
@ -21,18 +16,19 @@ class UnidadeFederativa(models.Model):
('SL', _('Sul')), ('SL', _('Sul')),
) )
codigo_ibge = models.PositiveIntegerField( codigo_ibge = models.PositiveIntegerField(
'código IBGE', _('código IBGE'),
primary_key=True, primary_key=True,
unique=True, unique=True,
help_text=_('Código do estado segundo IBGE.') help_text=_('Código do estado segundo IBGE.')
) )
nome = models.CharField(_('Nome UF'), max_length=25) nome = models.CharField(_('nome UF'), max_length=25)
# Campo de busca em caixa baixa sem acento # Campo de busca em caixa baixa sem acento
search_text = SearchField(field_names=['nome']) search_text = SearchField(field_names=['nome'])
sigla = models.CharField( sigla = models.CharField(
_('sigla'),
max_length=2, max_length=2,
unique=True, unique=True,
help_text=_("Exemplo") + ": <em>MG</em>.", help_text=_("Exemplo: <em>MG</em>."),
) )
regiao = models.CharField(_('região'), max_length=2, choices=REGIAO_CHOICES) regiao = models.CharField(_('região'), max_length=2, choices=REGIAO_CHOICES)
populacao = models.PositiveIntegerField(_('população')) populacao = models.PositiveIntegerField(_('população'))
@ -42,12 +38,12 @@ class UnidadeFederativa(models.Model):
verbose_name = _('Unidade Federativa') verbose_name = _('Unidade Federativa')
verbose_name_plural = _('Unidades Federativas') verbose_name_plural = _('Unidades Federativas')
def __unicode__(self): def __str__(self):
return self.nome return self.nome
class Mesorregiao(models.Model): class Mesorregiao(models.Model):
codigo_ibge = models.PositiveIntegerField( codigo_ibge = models.PositiveIntegerField(
_('Código IBGE'), _('código IBGE'),
primary_key=True, primary_key=True,
unique=True, unique=True,
help_text=_('Código da mesorregião segundo o IBGE') help_text=_('Código da mesorregião segundo o IBGE')
@ -57,59 +53,57 @@ class Mesorregiao(models.Model):
on_delete=models.CASCADE, on_delete=models.CASCADE,
verbose_name=_('UF') verbose_name=_('UF')
) )
nome = models.CharField(_("Nome mesorregião"), max_length=100) nome = models.CharField(_("nome mesorregião"), max_length=100)
# Campo de busca em caixa baixa sem acento # Campo de busca em caixa baixa sem acento
search_text = SearchField(field_names=['nome']) search_text = SearchField(field_names=['nome'])
class Meta: class Meta:
ordering = ('uf', 'nome',) ordering = ('uf', 'nome',)
verbose_name, verbose_name_plural = _('Mesorregião'), _('Mesorregiões') verbose_name = _('mesorregião'),
verbose_name_plural = _('mesorregiões')
def __unicode__(self): def __str__(self):
return self.nome return self.nome
class Microrregiao(models.Model): class Microrregiao(models.Model):
codigo_ibge = models.PositiveIntegerField( codigo_ibge = models.PositiveIntegerField(
_('Código IBGE'), _('código IBGE'),
primary_key=True, primary_key=True,
unique=True, unique=True,
help_text=_('Código da microrregião segundo o IBGE') help_text=_('Código da microrregião segundo o IBGE')
) )
mesorregiao = models.ForeignKey( mesorregiao = models.ForeignKey(
Mesorregiao, Mesorregiao,
on_delete=models.CASCADE on_delete=models.CASCADE,
verbose_name=_('mesorregião'),
) )
nome = models.CharField(_("Nome microrregião"), max_length=100) nome = models.CharField(_("nome microrregião"), max_length=100)
# Campo de busca em caixa baixa sem acento # Campo de busca em caixa baixa sem acento
search_text = SearchField(field_names=['nome']) search_text = SearchField(field_names=['nome'])
class Meta: class Meta:
ordering = ('nome',) ordering = ('nome',)
verbose_name, verbose_name_plural = _('Microrregião'), _('Microrregiões') verbose_name = _('microrregião')
verbose_name_plural = _('microrregiões')
def __unicode__(self): def __str__(self):
return "%s (%s)" % (self.nome, self.mesorregiao.nome) return f"{self.nome} ({self.mesorregiao.nome})"
class Municipio(models.Model): class Municipio(models.Model):
""" Modelo para representar as cidades brasileiras
"""
codigo_ibge = models.PositiveIntegerField( codigo_ibge = models.PositiveIntegerField(
_('código IBGE'), _('código IBGE'),
primary_key=True, primary_key=True,
unique=True, unique=True,
help_text=_('Código do município segundo IBGE.') help_text=_('Código do município segundo IBGE.')
) )
microrregiao = models.ForeignKey( microrregiao = models.ForeignKey(
Microrregiao, Microrregiao,
on_delete=models.PROTECT, on_delete=models.PROTECT,
verbose_name=_('Microrregião'), verbose_name=_('microrregião'),
blank=True, blank=True,
null=True null=True
) )
# codigo designado pelo Tribunal Superior Eleitoral
# codio designado pelo Tribunal Superior Eleitoral
codigo_tse = models.PositiveIntegerField( codigo_tse = models.PositiveIntegerField(
_('código TSE'), _('código TSE'),
unique=True, unique=True,
@ -126,51 +120,65 @@ class Municipio(models.Model):
# verdadeiro se o município é capital do estado # verdadeiro se o município é capital do estado
is_capital = models.BooleanField(_('capital'), default=False) is_capital = models.BooleanField(_('capital'), default=False)
populacao = models.PositiveIntegerField(_('população')) populacao = models.PositiveIntegerField(_('população'))
populacao.list_filter_range = [10000, 100000, 1000000]
is_polo = models.BooleanField(_('pólo'), default=False) is_polo = models.BooleanField(_('pólo'), default=False)
data_criacao = models.DateField(_('data de criação do município'), null=True, blank=True) data_criacao = models.DateField(
_('data de criação do município'),
null=True,
blank=True
)
# posição geográfica do município # posição geográfica do município
latitude = models.DecimalField( latitude = models.DecimalField(
_('latitude'),
max_digits=10, max_digits=10,
decimal_places=8, decimal_places=8,
null=True, null=True,
blank=True, blank=True,
help_text=_('Exemplo') + ': <em>-20,464</em>.' help_text=_('Exemplo: <em>-20,464</em>.')
) )
longitude = models.DecimalField( longitude = models.DecimalField(
_('longitude'),
max_digits=11, max_digits=11,
decimal_places=8, decimal_places=8,
null=True, null=True,
blank=True, blank=True,
help_text=_('Exemplo') + ': <em>-45,426</em>.' help_text=_('Exemplo: <em>-45,426</em>.')
)
idh = models.DecimalField(
_('IDH'),
help_text=_('Índice de desenvolvimento Humano'),
max_digits=4,
decimal_places=3,
validators=[MinValueValidator(0), MaxValueValidator(1)]
)
pib_total = models.DecimalField(
_('PIB total'),
max_digits=18,
decimal_places=3,
blank=True,
null=True
)
pib_percapita = models.DecimalField(
_('PIB per capita'),
max_digits=18,
decimal_places=3,
blank=True,
null=True
)
pib_ano = models.IntegerField(
_('Ano de apuração do PIB'),
blank=True,
null=True
) )
idh = models.DecimalField(_('IDH'), help_text=_('Índice de desenvolvimento Humano'), max_digits=4, decimal_places=3,
validators=[MinValueValidator(0), MaxValueValidator(1)])
idh.list_filter_range = [0.500, 0.800]
pib_total = models.DecimalField(_('PIB total'), max_digits=18, decimal_places=3, blank=True, null=True)
pib_percapita = models.DecimalField(_('PIB per capita'), max_digits=18, decimal_places=3, blank=True, null=True)
pib_ano = models.IntegerField(_('Ano de apuração do PIB'), blank=True, null=True)
class Meta: class Meta:
ordering = ('nome', 'codigo_ibge') ordering = ('nome', 'codigo_ibge')
verbose_name = _('município') verbose_name = _('município')
verbose_name_plural = _('municípios') verbose_name_plural = _('municípios')
def __unicode__(self): def __str__(self):
return "%s - %s" % (self.nome, self.uf) return f"{self.nome} - {self.uf}"
def get_google_maps_url(self):
return "http://maps.google.com.br/maps/mm?ie=UTF8&hl=pt-BR&t=h&ll=%s,%s&spn=1.61886,1.812744&z=9&source=embed" % \
(self.latitude, self.longitude)
class Telefone(models.Model): class Telefone(models.Model):
""" Modelo genérico para agrupar telefones dos modulos do sistema
"""
TELEFONE_CHOICES = ( TELEFONE_CHOICES = (
('F', _('Fixo')), ('F', _('Fixo')),
('M', _('Móvel')), ('M', _('Móvel')),
@ -179,16 +187,23 @@ class Telefone(models.Model):
) )
numero = models.CharField( numero = models.CharField(
_('número'), _('número'),
max_length=64, # TODO: diminuir tamanho de campo após migração de dados max_length=64,
help_text=_('Exemplo') + ': <em>(31)8851-9898</em>.', help_text=_('Exemplo: <em>(31)8851-9898</em>.'),
) )
tipo = models.CharField( tipo = models.CharField(
_('tipo'),
max_length=1, max_length=1,
choices=TELEFONE_CHOICES, choices=TELEFONE_CHOICES,
default='I' default='I'
) )
nota = models.CharField(max_length=70, null=True, blank=True) nota = models.CharField(max_length=70, null=True, blank=True)
ult_alteracao = models.DateTimeField(_('Última alteração'), null=True, blank=True, editable=False, auto_now=True) ult_alteracao = models.DateTimeField(
_('última alteração'),
null=True,
blank=True,
editable=False,
auto_now=True
)
# guarda o tipo do objeto (classe) vinculado a esse registro # guarda o tipo do objeto (classe) vinculado a esse registro
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE) content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
@ -203,22 +218,14 @@ class Telefone(models.Model):
ordering = ('numero',) ordering = ('numero',)
unique_together = ('numero', 'tipo') unique_together = ('numero', 'tipo')
def __unicode__(self): def __str__(self):
return unicode(self.numero) return self.numero
class Contato(models.Model): class Contato(models.Model):
""" Modelo generico para registrar contatos vinculados aos
modulos do sistema
"""
nome = models.CharField(_('nome completo'), max_length=120) nome = models.CharField(_('nome completo'), max_length=120)
nome.alphabetic_filter = True
nota = models.CharField(max_length=70, blank=True) nota = models.CharField(max_length=70, blank=True)
email = models.EmailField(_('e-mail'), blank=True) email = models.EmailField(_('e-mail'), blank=True)
telefones = GenericRelation(Telefone) telefones = GenericRelation(Telefone)
municipio = models.ForeignKey( municipio = models.ForeignKey(
Municipio, Municipio,
on_delete=models.SET_NULL, on_delete=models.SET_NULL,
@ -226,7 +233,6 @@ class Contato(models.Model):
blank=True, blank=True,
null=True, null=True,
) )
# guarda o tipo do objeto (classe) vinculado a esse registro # guarda o tipo do objeto (classe) vinculado a esse registro
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE) content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
# identificador do registro na classe vinculado a esse registro # identificador do registro na classe vinculado a esse registro
@ -241,10 +247,9 @@ class Contato(models.Model):
verbose_name = _('contato Interlegis') verbose_name = _('contato Interlegis')
verbose_name_plural = _('contatos Interlegis') verbose_name_plural = _('contatos Interlegis')
def __unicode__(self): def __str__(self):
return self.nome return self.nome
class Endereco(models.Model): class Endereco(models.Model):
TIPO_CHOICES = ( TIPO_CHOICES = (
('aeroporto', _('Aeroporto')), ('aeroporto', _('Aeroporto')),
@ -294,26 +299,22 @@ class Endereco(models.Model):
('outro', _('Outro')), ('outro', _('Outro')),
) )
# tipo do endereço obtido no site dos correios tipo = models.CharField(_('tipo'), max_length=15, choices=TIPO_CHOICES)
tipo = models.CharField(max_length=15, choices=TIPO_CHOICES)
logradouro = models.CharField( logradouro = models.CharField(
_('logradouro'),
max_length=100, max_length=100,
) )
logradouro.alphabetic_filter = True
numero = models.CharField(max_length=15, blank=True) numero = models.CharField(max_length=15, blank=True)
complemento = models.CharField(max_length=15, blank=True) complemento = models.CharField(max_length=15, blank=True)
# campo de texto livre
referencia = models.CharField(max_length=100, blank=True) referencia = models.CharField(max_length=100, blank=True)
bairro = models.CharField(max_length=100, blank=True) bairro = models.CharField(max_length=100, blank=True)
cep = models.CharField( cep = models.CharField(
_('CEP'), _('CEP'),
max_length=9, max_length=9,
blank=True, blank=True,
null=True, null=True,
help_text=_("Formato") + ": <em>XXXXX-XXX</em>." help_text=_("Formato: <em>XXXXX-XXX</em>.")
) )
municipio = models.ForeignKey( municipio = models.ForeignKey(
Municipio, Municipio,
on_delete=models.SET_NULL, on_delete=models.SET_NULL,
@ -321,8 +322,6 @@ class Endereco(models.Model):
blank=True, blank=True,
null=True, null=True,
) )
municipio.uf_filter = True
# guarda o tipo do objeto (classe) vinculado a esse registro # guarda o tipo do objeto (classe) vinculado a esse registro
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE) content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
# identificador do registro na classe vinculado a esse registro # identificador do registro na classe vinculado a esse registro
@ -337,6 +336,6 @@ class Endereco(models.Model):
verbose_name = _('endereço') verbose_name = _('endereço')
verbose_name_plural = _('endereços') verbose_name_plural = _('endereços')
def __unicode__(self): def __str__(self):
return self.tipo + ' ' + self.logradouro + ', ' + self.numero \ return (f"{self.tipo} {self.logradouro}, {self.numero}"
+ ' ' + self.complemento + ' - ' + self.bairro f"{self.complemento} - {self.bairro}")

3
sigi/apps/contatos/tests.py

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

2
sigi/apps/utils/__init__.py

@ -39,4 +39,4 @@ def queryset_ascii(self, request):
if 'q' in request.GET: if 'q' in request.GET:
request.GET._mutable = True request.GET._mutable = True
request.GET['q'] = to_ascii(request.GET['q']) request.GET['q'] = to_ascii(request.GET['q'])
return admin.ModelAdmin.queryset(self, request) return admin.ModelAdmin.get_queryset(self, request)

1
sigi/apps/utils/base_admin.py

@ -29,6 +29,5 @@ class BaseChangeList(ChangeList):
class BaseModelAdmin(admin.ModelAdmin): class BaseModelAdmin(admin.ModelAdmin):
def get_changelist(self, request, **kwargs): def get_changelist(self, request, **kwargs):
return BaseChangeList return BaseChangeList

97
sigi/apps/utils/filters.py

@ -1,31 +1,94 @@
# coding: utf-8 # coding: utf-8
import string import string
from django.contrib import admin from django.contrib import admin
from django.contrib.admin.options import IncorrectLookupParameters
from django.utils.translation import gettext as _
from django.core.exceptions import ValidationError
class AlphabeticFilter(admin.SimpleListFilter): class AlphabeticFilter(admin.SimpleListFilter):
# Human-readable title which will be displayed in the
# right admin sidebar just above the filter options.
title = '' title = ''
# Parameter for the filter that will be used in the URL query.
parameter_name = '' parameter_name = ''
def lookups(self, request, model_admin): def lookups(self, request, model_admin):
"""
Returns a list of tuples. The first element in each
tuple is the coded value for the option that will
appear in the URL query. The second element is the
human-readable name for the option that will appear
in the right sidebar.
"""
return ((letter, letter,) for letter in string.ascii_uppercase) return ((letter, letter,) for letter in string.ascii_uppercase)
def queryset(self, request, queryset): def queryset(self, request, queryset):
"""
Returns the filtered queryset based on the value
provided in the query string and retrievable via
`self.value()`.
"""
if self.value(): if self.value():
return queryset.filter((self.parameter_name + '__istartswith', self.value())) return queryset.filter(
(self.parameter_name + '__istartswith', self.value())
)
class RangeFilter(admin.FieldListFilter):
num_faixas = 4
parameter_name = None
def __init__(self, field, request, params, model, model_admin, field_path):
self.model = model
self.model_admin = model_admin
self.parameter_name = f'{field_path}__range'
super().__init__(field, request, params, model, model_admin, field_path)
if self.parameter_name in params:
value = params.pop(self.parameter_name)
self.used_parameters[self.parameter_name] = value
lookup_choices = self.lookups(request, model_admin)
if lookup_choices is None:
lookup_choices = ()
self.lookup_choices = list(lookup_choices)
def ranges(self, model):
tudo = model.objects.values_list(self.field_path, flat=True).order_by(
self.field_path)
passo = len(tudo) // self.num_faixas
ultimo = 0
for i in range(1, self.num_faixas):
yield (i, ultimo, tudo[i*passo])
ultimo = tudo[i*passo]
yield (self.num_faixas, ultimo, tudo.last())
def lookups(self, request, model_admin):
return ((value, _(f"de {min} até {max}"))
for value, min, max in self.ranges(self.model))
def has_output(self):
return self.model.objects.exists()
def value(self):
return self.used_parameters.get(self.parameter_name)
def expected_parameters(self):
return [self.parameter_name,]
def choices(self, changelist):
yield {
'selected': self.value() is None,
'query_string': changelist.get_query_string(
remove=[self.parameter_name]),
'display': _('All'),
}
for lookup, title in self.lookup_choices:
yield {
'selected': self.value() == str(lookup),
'query_string': changelist.get_query_string(
{self.parameter_name: lookup}
),
'display': title,
}
def queryset(self, request, queryset):
try:
for value, min, max in self.ranges(self.model):
if self.value() == str(value):
return queryset.filter(
(f'{self.field_path}__gte', min),
(f'{self.field_path}__lt', max)
)
except (ValueError, ValidationError) as e:
raise IncorrectLookupParameters(e)
return queryset

1
sigi/settings/base.py

@ -20,6 +20,7 @@ BASE_DIR = Path(__file__).resolve().parent.parent
INSTALLED_APPS = [ INSTALLED_APPS = [
'sigi.apps.servidores', 'sigi.apps.servidores',
'sigi.apps.contatos',
'django_bootstrap5', 'django_bootstrap5',
'django.forms', 'django.forms',
'django.contrib.admin', 'django.contrib.admin',

Loading…
Cancel
Save