from django.db import models class AnoCenso(models.Model): ano = models.PositiveSmallIntegerField(primary_key=True) class Meta: verbose_name = "ano do censo" verbose_name_plural = "anos do censo" ordering = ["-ano"] @property def ano_execucao(self) -> int: return self.ano + 1 def __str__(self) -> str: return str(self.ano) class UF(models.Model): codigo = models.PositiveSmallIntegerField(primary_key=True) nome = models.CharField(max_length=100, unique=True) class Meta: verbose_name = "UF" verbose_name_plural = "UFs" ordering = ["nome"] def __str__(self) -> str: return self.nome class Pais(models.Model): codigo = models.CharField(max_length=3, primary_key=True) nome = models.CharField(max_length=100, unique=True) class Meta: verbose_name = "pais" verbose_name_plural = "paises" ordering = ["nome"] def __str__(self) -> str: return self.nome class Municipio(models.Model): codigo = models.PositiveIntegerField(primary_key=True) nome = models.CharField(max_length=150) uf = models.ForeignKey(UF, on_delete=models.PROTECT, related_name="municipios") class Meta: verbose_name = "municipio" verbose_name_plural = "municipios" ordering = ["nome"] indexes = [ models.Index(fields=["nome"]), models.Index(fields=["uf", "nome"]), ] def __str__(self) -> str: return f"{self.nome} - {self.uf.nome}" class Curso(models.Model): id = models.BigAutoField(primary_key=True) codigo_mec = models.PositiveIntegerField(unique=True) descricao = models.CharField(max_length=200) situacao_funcionamento_curso = models.CharField(max_length=100, blank=True) licenciatura = models.BooleanField(default=False) ead = models.BooleanField(default=False) carga_horaria_total = models.PositiveIntegerField() polo = models.ForeignKey( "Polo", on_delete=models.PROTECT, null=True, blank=True, related_name="cursos", ) class Meta: verbose_name = "curso" verbose_name_plural = "cursos" ordering = ["descricao"] def __str__(self) -> str: return self.descricao class FallbackCurso(models.Model): texto_api = models.CharField(max_length=200, unique=True) texto_local = models.CharField(max_length=200) class Meta: verbose_name = "fallback de curso" verbose_name_plural = "fallbacks de curso" ordering = ["texto_api"] indexes = [ models.Index(fields=["texto_api"]), models.Index(fields=["texto_local"]), ] def __str__(self) -> str: return f"{self.texto_api} -> {self.texto_local}" class Instituicao(models.Model): codigo_inep = models.PositiveBigIntegerField(primary_key=True) nome = models.CharField(max_length=200, blank=True) class Meta: verbose_name = "instituicao" verbose_name_plural = "instituicoes" ordering = ["nome", "codigo_inep"] def __str__(self) -> str: return self.nome or str(self.codigo_inep) class Polo(models.Model): codigo = models.PositiveBigIntegerField(unique=True) descricao = models.CharField(max_length=200) class Meta: verbose_name = "polo" verbose_name_plural = "polos" ordering = ["descricao", "codigo"] def __str__(self) -> str: return self.descricao class Pessoa(models.Model): class CorRaca(models.IntegerChoices): NAO_DECLARADA = 0, "Aluno nao quis declarar cor/raca" BRANCA = 1, "Branca" PRETA = 2, "Preta" PARDA = 3, "Parda" AMARELA = 4, "Amarela" INDIGENA = 5, "Indigena" NAO_DISPOE = 6, "Nao dispoe da informacao" class Nacionalidade(models.IntegerChoices): BRASILEIRA_NATA = 1, "Brasileira nata" BRASILEIRA_NATURALIZADA = 2, "Brasileira por naturalizacao" ESTRANGEIRA = 3, "Estrangeira" class SimNaoNaoDispoe(models.IntegerChoices): NAO = 0, "Nao" SIM = 1, "Sim" NAO_DISPOE = 2, "Nao dispoe da informacao" class TipoEscolaEnsinoMedio(models.IntegerChoices): PRIVADA = 0, "Privado" PUBLICA = 1, "Publico" NAO_DISPOE = 2, "Nao dispoe da informacao" id_aluno_inep = models.PositiveBigIntegerField(null=True, blank=True) nome = models.CharField(max_length=120) cpf = models.CharField(max_length=11, unique=True) documento_estrangeiro = models.CharField(max_length=20, blank=True) data_nascimento = models.DateField(null=True, blank=True) cor_raca = models.PositiveSmallIntegerField(choices=CorRaca.choices) nacionalidade = models.PositiveSmallIntegerField(choices=Nacionalidade.choices) uf_nascimento = models.ForeignKey( UF, on_delete=models.PROTECT, null=True, blank=True, related_name="pessoas_nascidas", ) municipio_nascimento = models.ForeignKey( Municipio, on_delete=models.PROTECT, null=True, blank=True, related_name="pessoas_nascidas", ) pais_origem = models.ForeignKey( Pais, on_delete=models.PROTECT, related_name="pessoas_originarias", ) aluno_com_deficiencia = models.PositiveSmallIntegerField( choices=SimNaoNaoDispoe.choices ) deficiencia_cegueira = models.BooleanField(null=True, blank=True) deficiencia_baixa_visao = models.BooleanField(null=True, blank=True) deficiencia_visao_monocular = models.BooleanField(null=True, blank=True) deficiencia_surdez = models.BooleanField(null=True, blank=True) deficiencia_auditiva = models.BooleanField(null=True, blank=True) deficiencia_fisica = models.BooleanField(null=True, blank=True) deficiencia_surdocegueira = models.BooleanField(null=True, blank=True) deficiencia_intelectual = models.BooleanField(null=True, blank=True) deficiencia_tea = models.BooleanField(null=True, blank=True) deficiencia_altas_habilidades = models.BooleanField(null=True, blank=True) tipo_escola_ensino_medio = models.PositiveSmallIntegerField( choices=TipoEscolaEnsinoMedio.choices ) anos_censo = models.ManyToManyField( AnoCenso, blank=True, related_name="pessoas", ) atualizado_manualmente = models.BooleanField(default=False) class Meta: verbose_name = "pessoa" verbose_name_plural = "pessoas" ordering = ["nome"] indexes = [ models.Index(fields=["nome"]), models.Index(fields=["cpf"]), ] def __str__(self) -> str: return self.nome class Vinculo(models.Model): class PeriodoReferencia(models.IntegerChoices): PRIMEIRO_SEMESTRE = 1, "Primeiro semestre" SEGUNDO_SEMESTRE = 2, "Segundo semestre" class Turno(models.IntegerChoices): MATUTINO = 1, "Matutino" VESPERTINO = 2, "Vespertino" NOTURNO = 3, "Noturno" INTEGRAL = 4, "Integral" class Situacao(models.IntegerChoices): NAO_INFORMADA = 0, "Nao informada" CURSANDO = 2, "Cursando" MATRICULA_TRANCADA = 3, "Matricula trancada" DESVINCULADO = 4, "Desvinculado do curso" TRANSFERENCIA_INTERNA = 5, "Transferencia interna" FORMADO = 6, "Formado" FALECIDO = 7, "Falecido" class TipoSegundaLicenciatura(models.IntegerChoices): SEGUNDA_LICENCIATURA = 1, "Segunda licenciatura" FORMACAO_PEDAGOGICA = 2, "Formacao pedagogica" class TipoMobilidade(models.IntegerChoices): NACIONAL = 1, "Nacional" INTERNACIONAL = 2, "Internacional" class TipoPoliticaAcaoAfirmativa(models.IntegerChoices): LEI_COTAS = 1, "Reserva de vaga - Lei de Cotas" OUTRAS = 2, "Outras reservas de vagas ou programa diferenciado" pessoa = models.ForeignKey(Pessoa, on_delete=models.CASCADE, related_name="vinculos") ano_censo = models.ForeignKey( AnoCenso, on_delete=models.PROTECT, default=2025, related_name="vinculos", ) matricula = models.CharField( "matricula", max_length=20, blank=True, db_column="id_aluno_ies", ) periodo_referencia = models.PositiveSmallIntegerField( choices=PeriodoReferencia.choices, null=True, blank=True, ) curso = models.ForeignKey( Curso, on_delete=models.PROTECT, to_field="codigo_mec", related_name="vinculos", ) polo = models.ForeignKey( Polo, on_delete=models.PROTECT, null=True, blank=True, related_name="vinculos", ) turno = models.PositiveSmallIntegerField(choices=Turno.choices, null=True, blank=True) situacao = models.PositiveSmallIntegerField(choices=Situacao.choices) curso_origem = models.ForeignKey( Curso, on_delete=models.PROTECT, to_field="codigo_mec", null=True, blank=True, related_name="vinculos_originados", ) semestre_conclusao = models.PositiveSmallIntegerField( choices=PeriodoReferencia.choices, null=True, blank=True, ) aluno_parfor = models.BooleanField(null=True, blank=True) segunda_licenciatura_formacao_pedagogica = models.BooleanField(null=True, blank=True) tipo_segunda_licenciatura_formacao_pedagogica = models.PositiveSmallIntegerField( choices=TipoSegundaLicenciatura.choices, null=True, blank=True, ) semestre_ingresso = models.CharField(max_length=6) ingresso_vestibular = models.BooleanField() ingresso_enem = models.BooleanField() ingresso_avaliacao_seriada = models.BooleanField() ingresso_selecao_simplificada = models.BooleanField() ingresso_egresso_bi_li = models.BooleanField() ingresso_pec_g = models.BooleanField() ingresso_transferencia_ex_officio = models.BooleanField() ingresso_decisao_judicial = models.BooleanField() ingresso_vagas_remanescentes = models.BooleanField() ingresso_programas_especiais = models.BooleanField() mobilidade_academica = models.BooleanField(null=True, blank=True) tipo_mobilidade_academica = models.PositiveSmallIntegerField( choices=TipoMobilidade.choices, null=True, blank=True, ) mobilidade_ies_destino = models.ForeignKey( Instituicao, on_delete=models.PROTECT, null=True, blank=True, related_name="vinculos_mobilidade_destino", ) mobilidade_pais_destino = models.ForeignKey( Pais, on_delete=models.PROTECT, null=True, blank=True, related_name="vinculos_mobilidade_destino", ) financiamento_estudantil = models.BooleanField(null=True, blank=True) financiamento_fies = models.BooleanField(null=True, blank=True) financiamento_governo_estadual = models.BooleanField(null=True, blank=True) financiamento_governo_municipal = models.BooleanField(null=True, blank=True) financiamento_ies = models.BooleanField(null=True, blank=True) financiamento_entidades_externas = models.BooleanField(null=True, blank=True) financiamento_prouni_integral = models.BooleanField(null=True, blank=True) financiamento_prouni_parcial = models.BooleanField(null=True, blank=True) financiamento_nao_reembolsavel_entidades_externas = models.BooleanField( null=True, blank=True, ) financiamento_nao_reembolsavel_governo_estadual = models.BooleanField( null=True, blank=True, ) financiamento_nao_reembolsavel_ies = models.BooleanField(null=True, blank=True) financiamento_nao_reembolsavel_governo_municipal = models.BooleanField( null=True, blank=True, ) apoio_social = models.BooleanField() apoio_alimentacao = models.BooleanField(null=True, blank=True) apoio_moradia = models.BooleanField(null=True, blank=True) apoio_transporte = models.BooleanField(null=True, blank=True) apoio_material_didatico = models.BooleanField(null=True, blank=True) apoio_bolsa_trabalho = models.BooleanField(null=True, blank=True) apoio_bolsa_permanencia = models.BooleanField(null=True, blank=True) atividade_extracurricular = models.BooleanField() atividade_pesquisa = models.BooleanField(null=True, blank=True) bolsa_pesquisa = models.BooleanField(null=True, blank=True) atividade_extensao = models.BooleanField(null=True, blank=True) bolsa_extensao = models.BooleanField(null=True, blank=True) atividade_monitoria = models.BooleanField(null=True, blank=True) bolsa_monitoria = models.BooleanField(null=True, blank=True) atividade_estagio_nao_obrigatorio = models.BooleanField(null=True, blank=True) bolsa_estagio_nao_obrigatorio = models.BooleanField(null=True, blank=True) carga_horaria_total_aluno = models.PositiveIntegerField() carga_horaria_integralizada = models.PositiveIntegerField() ingressou_acao_afirmativa = models.BooleanField() tipo_politica_acao_afirmativa = models.PositiveSmallIntegerField( choices=TipoPoliticaAcaoAfirmativa.choices, null=True, blank=True, ) tipo_acao_afirmativa_lei_cotas = models.PositiveSmallIntegerField(null=True, blank=True) reserva_ppi = models.BooleanField(null=True, blank=True) reserva_renda = models.BooleanField(null=True, blank=True) reserva_pessoa_com_deficiencia = models.BooleanField(null=True, blank=True) reserva_escola_publica = models.BooleanField(null=True, blank=True) reserva_quilombola = models.BooleanField(null=True, blank=True) reserva_transgenero_travesti = models.BooleanField(null=True, blank=True) reserva_estudante_internacional = models.BooleanField(null=True, blank=True) reserva_refugiado_apatrida_visto_humanitario = models.BooleanField( null=True, blank=True, ) reserva_idoso = models.BooleanField(null=True, blank=True) reserva_povos_comunidades_tradicionais = models.BooleanField(null=True, blank=True) reserva_olimpiadas_conhecimento = models.BooleanField(null=True, blank=True) reserva_outros = models.BooleanField(null=True, blank=True) justificativa = models.PositiveSmallIntegerField(null=True, blank=True) atualizado_manualmente = models.BooleanField(default=False) class Meta: verbose_name = "vinculo" verbose_name_plural = "vinculos" ordering = ["pessoa__nome", "curso__descricao"] constraints = [ models.UniqueConstraint( fields=["pessoa", "curso", "ano_censo"], name="unique_vinculo_pessoa_curso_ano", ), ] indexes = [ models.Index(fields=["ano_censo"]), models.Index(fields=["situacao"]), models.Index(fields=["semestre_ingresso"]), ] def __str__(self) -> str: return f"{self.pessoa} - {self.curso}"