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.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')

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 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: <em>XXXXX-XXX</em>.', 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,
),
]

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)),
('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,
),
]

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,
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") + ": <em>MG</em>.",
help_text=_("Exemplo: <em>MG</em>."),
)
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') + ': <em>-20,464</em>.'
help_text=_('Exemplo: <em>-20,464</em>.')
)
longitude = models.DecimalField(
_('longitude'),
max_digits=11,
decimal_places=8,
null=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:
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') + ': <em>(31)8851-9898</em>.',
max_length=64,
help_text=_('Exemplo: <em>(31)8851-9898</em>.'),
)
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") + ": <em>XXXXX-XXX</em>."
help_text=_("Formato: <em>XXXXX-XXX</em>.")
)
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}")

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:
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)

1
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

97
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

1
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',

Loading…
Cancel
Save