mirror of https://github.com/interlegis/sigi.git
Sesostris Vieira
3 years ago
12 changed files with 338 additions and 178 deletions
@ -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') |
@ -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 |
|
@ -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'), |
||||
|
), |
||||
|
] |
@ -0,0 +1,3 @@ |
|||||
|
from django.test import TestCase |
||||
|
|
||||
|
# Create your tests here. |
@ -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 |
Loading…
Reference in new issue