diff --git a/sigi/apps/contatos/admin.py b/sigi/apps/contatos/admin.py
index 22b1d07..c20dc24 100644
--- a/sigi/apps/contatos/admin.py
+++ b/sigi/apps/contatos/admin.py
@@ -1,12 +1,12 @@
-# -*- coding: utf-8 -*-
from django.contrib import admin
from django.utils.translation import gettext as _
-from sigi.apps.contatos.filters import PopulationFilter
-from sigi.apps.contatos.models import (UnidadeFederativa, Mesorregiao, Microrregiao,
- Municipio, Telefone, Contato)
+from sigi.apps.utils.filters import RangeFilter
+from sigi.apps.contatos.models import (UnidadeFederativa, Mesorregiao,
+ Microrregiao, Municipio, Telefone,
+ Contato)
from sigi.apps.utils import queryset_ascii
-from sigi.apps.utils.base_admin import BaseModelAdmin
+
class MesorregiaoInline(admin.TabularInline):
model = Mesorregiao
@@ -14,35 +14,43 @@ class MesorregiaoInline(admin.TabularInline):
class MicrorregiaoInline(admin.TabularInline):
model = Microrregiao
-class UnidadeFederativaAdmin(BaseModelAdmin):
+@admin.register(UnidadeFederativa)
+class UnidadeFederativaAdmin(admin.ModelAdmin):
actions = None
list_display = ('codigo_ibge', 'nome', 'sigla', 'regiao', 'populacao')
list_display_links = ('codigo_ibge', 'nome')
- list_filter = ('regiao', 'populacao', PopulationFilter,)
+ list_filter = ('regiao', ('populacao', RangeFilter),)
search_fields = ('search_text', 'codigo_ibge', 'sigla', 'regiao')
get_queryset = queryset_ascii
inlines = (MesorregiaoInline, )
-class MesorregiaoAdmin(BaseModelAdmin):
+@admin.register(Mesorregiao)
+class MesorregiaoAdmin(admin.ModelAdmin):
actions = None
list_display = ('codigo_ibge', 'uf', 'nome')
list_display_links = ('codigo_ibge', 'nome')
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
inlines = (MicrorregiaoInline,)
-class MunicipioAdmin(BaseModelAdmin):
+@admin.register(Municipio)
+class MunicipioAdmin(admin.ModelAdmin):
actions = None
- list_display = ('codigo_ibge', 'codigo_tse', 'nome', 'uf', 'is_capital', 'populacao', 'is_polo', 'idh', 'pib_ano',
- 'pib_total', 'pib_percapita')
+ list_display = ('codigo_ibge', 'codigo_tse', 'nome', 'uf', 'is_capital',
+ 'populacao', 'is_polo', 'idh', 'pib_ano', 'pib_total',
+ 'pib_percapita')
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
fieldsets = (
(None, {
- 'fields': ('codigo_ibge', 'codigo_tse', 'nome', 'data_criacao', 'uf', 'microrregiao',
- 'is_capital', 'populacao', 'is_polo', 'idh', 'pib_ano', 'pib_total', 'pib_percapita')
+ 'fields': ('codigo_ibge', 'codigo_tse', 'nome', 'data_criacao',
+ 'uf', 'microrregiao', 'is_capital', 'populacao',
+ 'is_polo', 'idh', 'pib_ano', 'pib_total',
+ 'pib_percapita')
}),
(_('Posição geográfica'), {
'fields': ('latitude', 'longitude'),
@@ -50,23 +58,18 @@ class MunicipioAdmin(BaseModelAdmin):
)
search_fields = ('search_text', 'codigo_ibge', 'codigo_tse', 'uf__sigla')
-
-class TelefoneAdmin(BaseModelAdmin):
+@admin.register(Telefone)
+class TelefoneAdmin(admin.ModelAdmin):
list_display = ('numero', 'tipo', 'nota')
list_display_links = ('numero',)
list_filter = ('tipo',)
radio_fields = {'tipo': admin.VERTICAL}
search_fields = ('numero', 'tipo', 'nota')
-
-class ContatoAdmin(BaseModelAdmin):
+@admin.register(Contato)
+class ContatoAdmin(admin.ModelAdmin):
list_display = ('nome', 'nota', 'email', 'municipio')
list_display_links = ('nome',)
list_filter = ('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)
+ search_fields = ('nome', 'nota', 'email', 'municipio__nome',
+ 'municipio__uf__nome')
diff --git a/sigi/apps/contatos/apps.py b/sigi/apps/contatos/apps.py
new file mode 100644
index 0000000..2dd9391
--- /dev/null
+++ b/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')
diff --git a/sigi/apps/contatos/filters.py b/sigi/apps/contatos/filters.py
deleted file mode 100644
index a83fb1c..0000000
--- a/sigi/apps/contatos/filters.py
+++ /dev/null
@@ -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
diff --git a/sigi/apps/contatos/migrations/0001_initial.py b/sigi/apps/contatos/migrations/0001_initial.py
index 9541e20..95f1a0c 100644
--- a/sigi/apps/contatos/migrations/0001_initial.py
+++ b/sigi/apps/contatos/migrations/0001_initial.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
@@ -21,7 +20,7 @@ class Migration(migrations.Migration):
('nota', models.CharField(max_length=70, blank=True)),
('email', models.EmailField(max_length=75, verbose_name='e-mail', blank=True)),
('object_id', models.PositiveIntegerField()),
- ('content_type', models.ForeignKey(to='contenttypes.ContentType')),
+ ('content_type', models.ForeignKey(to='contenttypes.ContentType', on_delete=models.CASCADE)),
],
options={
'ordering': ('nome',),
@@ -42,7 +41,7 @@ class Migration(migrations.Migration):
('bairro', models.CharField(max_length=100, blank=True)),
('cep', models.CharField(help_text='Formato: XXXXX-XXX.', max_length=9, null=True, verbose_name='CEP', blank=True)),
('object_id', models.PositiveIntegerField()),
- ('content_type', models.ForeignKey(to='contenttypes.ContentType')),
+ ('content_type', models.ForeignKey(to='contenttypes.ContentType', on_delete=models.CASCADE)),
],
options={
'ordering': ('logradouro', 'numero'),
@@ -87,7 +86,7 @@ class Migration(migrations.Migration):
('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)),
('object_id', models.PositiveIntegerField()),
- ('content_type', models.ForeignKey(to='contenttypes.ContentType')),
+ ('content_type', models.ForeignKey(to='contenttypes.ContentType', on_delete=models.CASCADE)),
],
options={
'ordering': ('numero',),
@@ -118,19 +117,19 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='municipio',
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,
),
migrations.AddField(
model_name='endereco',
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,
),
migrations.AddField(
model_name='contato',
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,
),
]
diff --git a/sigi/apps/contatos/migrations/0002_auto_20151104_0810.py b/sigi/apps/contatos/migrations/0002_auto_20151104_0810.py
index c95d8c2..b35632a 100644
--- a/sigi/apps/contatos/migrations/0002_auto_20151104_0810.py
+++ b/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)),
('nome', models.CharField(max_length=100, verbose_name='Nome mesorregi\xe3o')),
('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={
'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)),
('nome', models.CharField(max_length=100, verbose_name='Nome microrregi\xe3o')),
('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={
'ordering': ('mesorregiao', 'nome'),
@@ -53,7 +53,7 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='municipio',
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,
),
]
diff --git a/sigi/apps/contatos/migrations/0005_alter_mesorregiao_options_alter_microrregiao_options_and_more.py b/sigi/apps/contatos/migrations/0005_alter_mesorregiao_options_alter_microrregiao_options_and_more.py
new file mode 100644
index 0000000..941d434
--- /dev/null
+++ b/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: -20,464.', 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: -45,426.', 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: MG.', max_length=2, unique=True, verbose_name='sigla'),
+ ),
+ ]
diff --git a/sigi/apps/contatos/models.py b/sigi/apps/contatos/models.py
index 87282b2..6a00d5e 100644
--- a/sigi/apps/contatos/models.py
+++ b/sigi/apps/contatos/models.py
@@ -1,18 +1,13 @@
-# -*- coding: utf-8 -*-
from django.contrib.contenttypes.fields import (GenericForeignKey,
GenericRelation)
from django.contrib.contenttypes.models import ContentType
from django.core.validators import MaxValueValidator, MinValueValidator
from django.db import models
from django.utils.translation import gettext as _
-
from sigi.apps.utils import SearchField
class UnidadeFederativa(models.Model):
-
- """ Modelo que representa um estado brasileiro
- """
REGIAO_CHOICES = (
('CO', _('Centro-Oeste')),
('NE', _('Nordeste')),
@@ -21,18 +16,19 @@ class UnidadeFederativa(models.Model):
('SL', _('Sul')),
)
codigo_ibge = models.PositiveIntegerField(
- 'código IBGE',
+ _('código IBGE'),
primary_key=True,
unique=True,
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
search_text = SearchField(field_names=['nome'])
sigla = models.CharField(
+ _('sigla'),
max_length=2,
unique=True,
- help_text=_("Exemplo") + ": MG.",
+ help_text=_("Exemplo: MG."),
)
regiao = models.CharField(_('região'), max_length=2, choices=REGIAO_CHOICES)
populacao = models.PositiveIntegerField(_('população'))
@@ -42,12 +38,12 @@ class UnidadeFederativa(models.Model):
verbose_name = _('Unidade Federativa')
verbose_name_plural = _('Unidades Federativas')
- def __unicode__(self):
+ def __str__(self):
return self.nome
class Mesorregiao(models.Model):
codigo_ibge = models.PositiveIntegerField(
- _('Código IBGE'),
+ _('código IBGE'),
primary_key=True,
unique=True,
help_text=_('Código da mesorregião segundo o IBGE')
@@ -57,59 +53,57 @@ class Mesorregiao(models.Model):
on_delete=models.CASCADE,
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
search_text = SearchField(field_names=['nome'])
class Meta:
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
class Microrregiao(models.Model):
codigo_ibge = models.PositiveIntegerField(
- _('Código IBGE'),
+ _('código IBGE'),
primary_key=True,
unique=True,
help_text=_('Código da microrregião segundo o IBGE')
)
mesorregiao = models.ForeignKey(
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
search_text = SearchField(field_names=['nome'])
class Meta:
ordering = ('nome',)
- verbose_name, verbose_name_plural = _('Microrregião'), _('Microrregiões')
+ verbose_name = _('microrregião')
+ verbose_name_plural = _('microrregiões')
- def __unicode__(self):
- return "%s (%s)" % (self.nome, self.mesorregiao.nome)
+ def __str__(self):
+ return f"{self.nome} ({self.mesorregiao.nome})"
class Municipio(models.Model):
-
- """ Modelo para representar as cidades brasileiras
- """
codigo_ibge = models.PositiveIntegerField(
_('código IBGE'),
primary_key=True,
unique=True,
help_text=_('Código do município segundo IBGE.')
)
-
microrregiao = models.ForeignKey(
Microrregiao,
on_delete=models.PROTECT,
- verbose_name=_('Microrregião'),
+ verbose_name=_('microrregião'),
blank=True,
null=True
)
-
- # codio designado pelo Tribunal Superior Eleitoral
+ # codigo designado pelo Tribunal Superior Eleitoral
codigo_tse = models.PositiveIntegerField(
_('código TSE'),
unique=True,
@@ -126,51 +120,65 @@ class Municipio(models.Model):
# verdadeiro se o município é capital do estado
is_capital = models.BooleanField(_('capital'), default=False)
populacao = models.PositiveIntegerField(_('população'))
- populacao.list_filter_range = [10000, 100000, 1000000]
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
latitude = models.DecimalField(
+ _('latitude'),
max_digits=10,
decimal_places=8,
null=True,
blank=True,
- help_text=_('Exemplo') + ': -20,464.'
+ help_text=_('Exemplo: -20,464.')
)
longitude = models.DecimalField(
+ _('longitude'),
max_digits=11,
decimal_places=8,
null=True,
blank=True,
- help_text=_('Exemplo') + ': -45,426.'
+ help_text=_('Exemplo: -45,426.')
+ )
+ 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:
ordering = ('nome', 'codigo_ibge')
verbose_name = _('município')
verbose_name_plural = _('municípios')
- def __unicode__(self):
- return "%s - %s" % (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)
-
+ def __str__(self):
+ return f"{self.nome} - {self.uf}"
class Telefone(models.Model):
-
- """ Modelo genérico para agrupar telefones dos modulos do sistema
- """
TELEFONE_CHOICES = (
('F', _('Fixo')),
('M', _('Móvel')),
@@ -179,16 +187,23 @@ class Telefone(models.Model):
)
numero = models.CharField(
_('número'),
- max_length=64, # TODO: diminuir tamanho de campo após migração de dados
- help_text=_('Exemplo') + ': (31)8851-9898.',
+ max_length=64,
+ help_text=_('Exemplo: (31)8851-9898.'),
)
tipo = models.CharField(
+ _('tipo'),
max_length=1,
choices=TELEFONE_CHOICES,
default='I'
)
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
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
@@ -203,22 +218,14 @@ class Telefone(models.Model):
ordering = ('numero',)
unique_together = ('numero', 'tipo')
- def __unicode__(self):
- return unicode(self.numero)
-
+ def __str__(self):
+ return self.numero
class Contato(models.Model):
-
- """ Modelo generico para registrar contatos vinculados aos
- modulos do sistema
- """
nome = models.CharField(_('nome completo'), max_length=120)
- nome.alphabetic_filter = True
nota = models.CharField(max_length=70, blank=True)
-
email = models.EmailField(_('e-mail'), blank=True)
telefones = GenericRelation(Telefone)
-
municipio = models.ForeignKey(
Municipio,
on_delete=models.SET_NULL,
@@ -226,7 +233,6 @@ class Contato(models.Model):
blank=True,
null=True,
)
-
# guarda o tipo do objeto (classe) vinculado a esse registro
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
# identificador do registro na classe vinculado a esse registro
@@ -241,10 +247,9 @@ class Contato(models.Model):
verbose_name = _('contato Interlegis')
verbose_name_plural = _('contatos Interlegis')
- def __unicode__(self):
+ def __str__(self):
return self.nome
-
class Endereco(models.Model):
TIPO_CHOICES = (
('aeroporto', _('Aeroporto')),
@@ -294,26 +299,22 @@ class Endereco(models.Model):
('outro', _('Outro')),
)
- # tipo do endereço obtido no site dos correios
- tipo = models.CharField(max_length=15, choices=TIPO_CHOICES)
+ tipo = models.CharField(_('tipo'), max_length=15, choices=TIPO_CHOICES)
logradouro = models.CharField(
+ _('logradouro'),
max_length=100,
)
- logradouro.alphabetic_filter = True
numero = 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)
bairro = models.CharField(max_length=100, blank=True)
-
cep = models.CharField(
_('CEP'),
max_length=9,
blank=True,
null=True,
- help_text=_("Formato") + ": XXXXX-XXX."
+ help_text=_("Formato: XXXXX-XXX.")
)
-
municipio = models.ForeignKey(
Municipio,
on_delete=models.SET_NULL,
@@ -321,8 +322,6 @@ class Endereco(models.Model):
blank=True,
null=True,
)
- municipio.uf_filter = True
-
# guarda o tipo do objeto (classe) vinculado a esse registro
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
# identificador do registro na classe vinculado a esse registro
@@ -337,6 +336,6 @@ class Endereco(models.Model):
verbose_name = _('endereço')
verbose_name_plural = _('endereços')
- def __unicode__(self):
- return self.tipo + ' ' + self.logradouro + ', ' + self.numero \
- + ' ' + self.complemento + ' - ' + self.bairro
+ def __str__(self):
+ return (f"{self.tipo} {self.logradouro}, {self.numero}"
+ f"{self.complemento} - {self.bairro}")
diff --git a/sigi/apps/contatos/tests.py b/sigi/apps/contatos/tests.py
new file mode 100644
index 0000000..7ce503c
--- /dev/null
+++ b/sigi/apps/contatos/tests.py
@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.
diff --git a/sigi/apps/utils/__init__.py b/sigi/apps/utils/__init__.py
index 987ce86..beb28bd 100644
--- a/sigi/apps/utils/__init__.py
+++ b/sigi/apps/utils/__init__.py
@@ -39,4 +39,4 @@ def queryset_ascii(self, request):
if 'q' in request.GET:
request.GET._mutable = True
request.GET['q'] = to_ascii(request.GET['q'])
- return admin.ModelAdmin.queryset(self, request)
+ return admin.ModelAdmin.get_queryset(self, request)
diff --git a/sigi/apps/utils/base_admin.py b/sigi/apps/utils/base_admin.py
index b76370a..394a9f8 100644
--- a/sigi/apps/utils/base_admin.py
+++ b/sigi/apps/utils/base_admin.py
@@ -29,6 +29,5 @@ class BaseChangeList(ChangeList):
class BaseModelAdmin(admin.ModelAdmin):
-
def get_changelist(self, request, **kwargs):
return BaseChangeList
diff --git a/sigi/apps/utils/filters.py b/sigi/apps/utils/filters.py
index 0551776..6a9361d 100644
--- a/sigi/apps/utils/filters.py
+++ b/sigi/apps/utils/filters.py
@@ -1,31 +1,94 @@
# coding: utf-8
import string
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):
- # Human-readable title which will be displayed in the
- # right admin sidebar just above the filter options.
title = ''
-
- # Parameter for the filter that will be used in the URL query.
parameter_name = ''
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)
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():
- 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
\ No newline at end of file
diff --git a/sigi/settings/base.py b/sigi/settings/base.py
index 3464552..85289e1 100644
--- a/sigi/settings/base.py
+++ b/sigi/settings/base.py
@@ -20,6 +20,7 @@ BASE_DIR = Path(__file__).resolve().parent.parent
INSTALLED_APPS = [
'sigi.apps.servidores',
+ 'sigi.apps.contatos',
'django_bootstrap5',
'django.forms',
'django.contrib.admin',