Desarrollo e implementación del Sistema de Información ...

61
1 Desarrollo e implementación del Sistema de Información Académica y Administrativa (SIAA) del Centro de Radioastronomía y Astrofísica (CRyA) de la UNAM Campus Morelia Leonardo Arroyo 1 1 Instituto de Radioastronomía y Astrofísica, UNAM, Campus Morelia Resumen: Este documento describe el desarrollo e implementación de la aplicación web SIAA (Sistema de Información Académica y Administrativa). Este desarrollo surge por la necesidad de tener un repositorio de información generada por las actividades académicas de los investigadores en el centro. Cada año los investigadores del CRyA deben informar a la dirección y secretaría académica sobre las actividades de investigación, académicas y divulgación que tuvieron lugar durante el periodo. Inicialmente esta información se entregaba a manera de reporte escrito, donde se describen las actividades. Este reporte era en formato libre, por lo que cada investigador seguía su propia secuencia y organización de la información. A su vez estos reportes servían como evidencia para respaldar la información que se reporta al Consejo Técnico de la Investigación Científica de la UNAM (CTIC). Dado el crecimiento de la planta de investigadores y posdoctorados, el filtrado de la información recabada mediante los reportes escritos se convertía en una tarea cada vez más compleja. Por lo anterior se desarrolló una aplicación Para que los investigadores, técnicos académicos y posdoctorados de forma individual reporten la información de sus actividades, siguiendo un formato unificado y simplificado, la cual pudieran ir subiendo su información a lo largo del año, evitando una carga adicional al final del periodo académico. Adicionalmente, toda la información se puede manejar electrónicamente, permitiendo consultar la información de manera ágil y resumida, facilitando a su vez la elaboración de los reportes para el CTIC. 1 INTRODUCCIÓN Los investigadores del Centro de Radioastronomía y Astrofísica (CRyA) cada año deben entregar a la dirección un reporte donde especifican las actividades académicas, de investigación y divulgación que realizaron durante el periodo. El CTIC por su parte, solicita a la dirección que cada año al finalizar las actividades ingrese a una aplicación web donde debe suministrar información solicitada, la cual en su mayoría procede de la información que los investigadores proporcionan mediante su informe anual de actividades.

Transcript of Desarrollo e implementación del Sistema de Información ...

Page 1: Desarrollo e implementación del Sistema de Información ...

1

Desarrollo e implementación del Sistema de

Información Académica y Administrativa (SIAA)

del Centro de Radioastronomía y Astrofísica

(CRyA) de la UNAM Campus Morelia

Leonardo Arroyo1 1Instituto de Radioastronomía y Astrofísica, UNAM, Campus Morelia

Resumen: Este documento describe el desarrollo e implementación de la aplicación

web SIAA (Sistema de Información Académica y Administrativa). Este desarrollo

surge por la necesidad de tener un repositorio de información generada por las

actividades académicas de los investigadores en el centro. Cada año los

investigadores del CRyA deben informar a la dirección y secretaría académica sobre

las actividades de investigación, académicas y divulgación que tuvieron lugar

durante el periodo. Inicialmente esta información se entregaba a manera de reporte

escrito, donde se describen las actividades. Este reporte era en formato libre, por lo

que cada investigador seguía su propia secuencia y organización de la información.

A su vez estos reportes servían como evidencia para respaldar la información que se

reporta al Consejo Técnico de la Investigación Científica de la UNAM (CTIC). Dado

el crecimiento de la planta de investigadores y posdoctorados, el filtrado de la

información recabada mediante los reportes escritos se convertía en una tarea cada

vez más compleja. Por lo anterior se desarrolló una aplicación Para que los

investigadores, técnicos académicos y posdoctorados de forma individual reporten la

información de sus actividades, siguiendo un formato unificado y simplificado, la

cual pudieran ir subiendo su información a lo largo del año, evitando una carga

adicional al final del periodo académico. Adicionalmente, toda la información se

puede manejar electrónicamente, permitiendo consultar la información de manera

ágil y resumida, facilitando a su vez la elaboración de los reportes para el CTIC.

1 INTRODUCCIÓN

Los investigadores del Centro de Radioastronomía y Astrofísica (CRyA) cada año deben entregar a la

dirección un reporte donde especifican las actividades académicas, de investigación y divulgación que

realizaron durante el periodo. El CTIC por su parte, solicita a la dirección que cada año al finalizar las

actividades ingrese a una aplicación web donde debe suministrar información solicitada, la cual en su

mayoría procede de la información que los investigadores proporcionan mediante su informe anual de

actividades.

Page 2: Desarrollo e implementación del Sistema de Información ...

2

Debido a lo anterior se desarrolló una aplicación en la que los investigadores y posdoctorados colocan la

información referente a sus actividades a manera de reporte. Esta aplicación es un compendio de plantillas

que los investigadores llenan con la información que se les solicita. Además estas plantillas cuentan con

campos desplegables donde el usuario solo debe seleccionar la opción adecuada, de esta manera se

mantiene un estándar en la recolección de la información de tal manera que es más fácil clasificar para ser

entregada a CTIC.

Al tener toda la información recolectada es más sencillo para la dirección del centro disponer de está cada

vez que lo necesita, por ejemplo, para la entrega de informe de actividades, entrega de documentos, a la

vez que es una plataforma de consulta para los investigadores, quienes pueden recurrir a ésta para precisar

la información sobre algún evento o actividad que hayan realizado en un periodo determinado. Es posible

además obtener una versión impresa del compendio de actividades a manera de informe para entrega de

un periodo determinado.

En esta primera etapa de la aplicación el SIAA incluye las áreas académicas y de divulgación ya

mencionadas, además de la parte administrativa de los proyectos. En éstos se mantiene un registro de los

recursos económicos que se administran, así como su procedencia, participantes y responsables.

Como detalle técnico general, esta aplicación fue diseñada siguiendo un modelo de tres capas MVC1

(Modelo, Vista, Controlador), el cual separa los datos de la forma en como son tratados y después

presentados. Se hablará a detalle de este modelo en el documento. El uso de un modelo de construcción

separado da mayor flexibilidad para escalar y readaptar una aplicación a futuras versiones que requieran

información adicional (de ser necesario).

Para etapas posteriores se prevee la integración de otras áreas, como por ejemplo, la administrativa.

2 OBJETIVO

Elaborar un sistema que permita el almacenamiento de datos de actividades académicas y administrativas

del CRyA para su posterior consulta a manera de reportes con información resumida, clasificada y

ordenada.

3 PARTE 1: DISEÑO CONCEPTUAL DE LA APLICACIÓN Y LA SELECCIÓN DE LAS

HERRAMIENTAS PARA EL DESARROLLO

Bajo la premisa de tener un repositorio de datos que permitiera la consulta simplificada y la generación

de informes anuales de los investigadores del CRyA, se comenzó la conceptualización de la aplicación.

La idea de la aplicación siempre estuvo enfocada a la web. Debido a los diferentes sistemas operativos

que se utilizan en el centro, las constantes salidas con motivos académicos y la necesidad de movilidad

que impera en los investigadores del CRyA, la idea de una aplicación de escritorio quedaba completamente

corta para cubrir estas necesidades. La solución de una aplicación web solucionaba todos estos conflictos 1 "Django documentation." 2011. 18 Aug. 2015 <https://docs.djangoproject.com/>

Page 3: Desarrollo e implementación del Sistema de Información ...

3

de compatibilidad y movilidad, pero aún quedaba definir la solución de las herramientas que se emplearían

para el desarrollo.

En una primera revisión de las necesidades se pensó en utilizar PHP como lenguaje de programación y

MySQL como administrador de bases de datos. Pero conforme a la estructura de datos inicial se le iban

aumentando características y en vista de un crecimiento constante a futuro, se decidió que la mejor opción

era hacer una implementación siguiendo un modelo MVC.

Una manera ágil de programar una aplicación bajo el modelo MVC, es utilizando un framework2 dentro

del lenguaje PHP existe una infinidad, cada uno tiene su propia curva de aprendizaje.

Finalmente se decidió no utilizar PHP como lenguaje, sino Python, debido a la flexibilidad y simplicidad

del lenguaje, además de la experiencia con la que ya se cuenta trabajando con este lenguaje. Para Python

se utilizó el framework Django. Este framework provee de funcionalidades muy amplias y escalables para

la construcción de aplicaciones web y manejo de bases de datos respetando el modelo MVC. De esta

manera tendríamos una aplicación escalable y de fácil mantenimiento.

Los recursos técnicos utilizados para la implementación fueron:

1. Servidor Linux CentOS 6.6

2. Apache 2.2.15

3. Django Framework 1.4

4. Python 2.6.6

3.1 Características principales del Framework Django

Django es un framework web de código abierto escrito en Python que permite construir aplicaciones web.

Django fue inicialmente desarrollado para gestionar aplicaciones web de páginas orientadas a noticias de

World Online. Más tarde se liberó bajo licencia BSD.

Un framework es una estructura lógica y conceptual que brinda herramientas que permiten la agilidad en

el desarrollo. Permite abstraer problemas comunes al desarrollo web y proporciona atajos para tareas de

programación frecuentes. Un framework web resuelve los siguientes problemas:

● Proporciona un método para hacer corresponder peticiones URL con el código que maneja las

peticiones asignando un código a ejecutarse en cada URL.

● Facilita mostrar, validar y volver a mostrar formularios HTML.

● Convierte la entrada que envía el usuario en estructuras de datos que se pueden manipular.

● Ayuda a separar el contenido de la presentación mediante un sistema de plantillas, de manera que

se pueda cambiar el aspecto de un sitio web sin afectar al contenido, y viceversa.

● Se integra cómodamente con las capas de almacenamiento (por ejemplo bases de datos).

2 En términos de desarrollo de software, un framework es una estructura conceptual y tecnológica que brinda herramientas

pre construidas para facilitar el armado de un programa. Dependiendo de la implementación del framework, éste brinda

funcionalidades que ya no será necesario que el programador diseñe. Al ser una estructura o modelo, éste se apega a ciertas

normas o estándares.

Page 4: Desarrollo e implementación del Sistema de Información ...

4

Django sigue la arquitectura del "modelo-vista-controlador" (MVC).

Modelo - Vista - Controlador (MVC)

La arquitectura MVC es un patrón que define por separado el Modelo (Datos), la Vista (interfaz de usuario

y forma en como se presentan los datos) y el Controlador (lógica de cómo interactúan los datos y el

usuario). De esta forma, dividimos el sistema en tres capas manipulables de forma independiente, pero

capaz de interactuar eficientemente una con la otra.

En el modelo MVC se debe entender la división de todo el sistema en tres elementos y cómo estos

componentes se comunican unos con otros, con otras vistas y controladores externos al modelo principal.

Para ello, es importante saber que el controlador interpreta las entradas del usuario (tanto teclado como el

ratón), enviado el mensaje de acción al modelo y a la vista para que se proceda con los cambios que se

consideren adecuados. En la imagen 3.1 se muestra un esquema para ilustrar el modelo.

Imagen 3.1 Esquema del modelo-vista-controlador (MVC)

Django toma el MVC y lo redefine como Modelo-Template-Controlador (MTV) el cual es una adaptación

conceptual de los elementos que intervienen en cada una de las capas, como se muestra en la imagen 3.2

y se define de la siguiente manera:

● El modelo en Django sigue siendo modelo

● La vista en Django se llama Plantilla (Template)

● El controlador en Django se llama Vista

Page 5: Desarrollo e implementación del Sistema de Información ...

5

Imagen 3.2 Modelo MTV de Django.

El modelo: Define los datos almacenados, se encuentra en forma de clases de Python, cada tipo de dato

que debe ser almacenado se encuentra en una variable con ciertos parámetros, posee métodos también.

Todo esto permite indicar y controlar el comportamiento de los datos.

La vista: Se presenta en forma de funciones en Python, su propósito es determinar qué datos serán

visualizados. El ORM (Object Relation-Mapping) de Django permite escribir código Python en lugar de

SQL para hacer las consultas que necesita la vista. La vista también se encarga de tareas conocidas como

el envío de correo electrónico, la autenticación con servicios externos y la validación de datos a través de

formularios. Lo más importante a entender con respecto a la vista es que no tiene nada que ver con el

estilo de presentación de los datos, sólo se encarga de los datos, la presentación es tarea de la plantilla.

La plantilla: Es básicamente una página HTML con algunas etiquetas extras propias de Django, no

solamente crea contenido en HTML (también XML, CSS, Javascript, CSV, etc). La plantilla recibe los

datos de la vista y luego los organiza para la presentación al navegador web. Las etiquetas que Django usa

para las plantillas permiten que sea flexible para los diseñadores del frontend, incluso tiene estructuras de

datos como if, por si fuera necesaria una presentación lógica de los datos, estas estructuras son limitadas

para evitar el uso de código Python.

Cabe aclarar que aunque el modelo utilizado por Django, MTV, es solo una adaptación del MVC. No

representa ningún paradigma distinto.

3.2 Estructura del proyecto SIAA en Django

Las aplicaciones en Django deben respetar un modelo jerárquico de directorios. En el directorio raíz del

proyecto localizamos los siguientes archivos:

__init__.py: Este es un archivo vacío que le dice a Python que debe considerar este directorio

como un paquete de Python.

manage.py: Este archivo contiene una porción de código que permite interactuar con el proyecto

de Django de muchas formas, entre las que destacan la construcción del modelo de datos en SQL,

la modificación del mismo y la interacción en modo de pruebas.

Page 6: Desarrollo e implementación del Sistema de Información ...

6

settings.py: Este archivo contiene todas las configuraciones para el proyecto.

urls.py: Contiene las rutas que están disponibles en el proyecto.

En el apéndice A se muestra el código fuente de los archivos mencionados.

Dentro del directorio raíz se localizan tantos directorios como aplicaciones tenemos. Un proyecto de

Django está formado por n cantidad de aplicaciones, cada aplicación es tratada como un subconjunto de

datos y rutinas que se ejecutan para obtener un resultado. En el caso del SIAA, se consideró cada área a

capturar como una aplicación por separado teniendo así las siguientes aplicaciones:

Académicos: en este módulo se almacena información de los investigadores, posdoctorados,

técnicos académicos e información adicional para el reporte.

Distinciones: este módulo permite la captura y administración de los premios recibidos en el año,

así como los premios que hayan recibido los alumnos tutorados de cada investigador.

Divulgación: los rubros que se cubren para la captura de datos y su administración en este módulo

son presentaciones en eventos de divulgación, organización de eventos de divulgación, artículos

de divulgación publicados en medios escritos y electrónicos, producciones editoriales, entrevistas

que hayan recibido y producción de programas de radio, tv e internet.

Docencia: Esta aplicación maneja información relacionada a las actividades docentes, por

ejemplo, participación en comités tutorales, asesoría de alumnos, cursos de licenciatura impartidos

tanto en la UNAM como en otras instituciones, cursos de posgrado impartidos tanto en la UNAM

como en otras instituciones, cursos externos, dirección de tesis y trabajos escritos, participaciones

sínodos de exámenes generales, de grado temáticos y de candidatura. Parte de esta información es

llenada por el departamento de posgrado del centro, y cada usuario verá de manera personal, y sin

posibilidad de modificar la información que le corresponde.

Investigación: En esta aplicación se administra la información derivada de trabajos de

investigación en los que se participa durante el año. En esta área los investigadores reportan

información de los artículos publicados, memorias, artículos en extenso, capítulos en libros, libros

que hayan editado, reportes técnicos y un rubro donde se reporta todo el material que no

corresponde a alguna de las clasificaciones mencionadas.

Intercambio: Se reporta aquí todo lo relacionado con estancias sabáticas, estancias de trabajo por

parte de los investigadores o de visitantes tanto nacionales como en el extranjero, también se

reportan las visitas que hubo durante el año tanto de investigadores del CRyA a otros lugares como

de los visitantes foráneos que el CRyA recibió.

Proyectos: aquí se describen los proyectos en que el CRyA participa, Esta información es

proporcionada por el departamento de proyectos, quien se encarga de ingresar la información sobre

los proyectos y convenios activos y en proceso, como son: a) los recursos b) los responsables c)

los participantes. Adicionalmente los investigadores pueden reportar cualquier otro tipo de

proyecto en el que hayan participado por ejemplo de observación o supercómputo.

Vinculación: Este módulo permite administrar y recabar información relacionada a eventos y

actividades académicas entre pares, por ejemplo arbitrajes en revistas, proyectos, asesorías,

asistencia y presentación a eventos académicos, organización de eventos académicos y cursos de

superación académica.

Generales: Este módulo es de uso exclusivo para administradores del sistema, en ella se

almacenan valores predeterminados que son utilizados por el sistema para llenado de menús

desplegables, información por default y procesamiento de los datos para su administración y

representación.

Page 7: Desarrollo e implementación del Sistema de Información ...

7

Cada directorio de una aplicación en el proyecto contiene los siguientes archivos:

admin.py : En este archivo se crea la definición de los modelos y elementos que irán en la

aplicación de administración, la cual es un backend prediseñado.

__init__.py: Este es un archivo vacío que le dice a Python que debe considerar este directorio

como un paquete de Python.

models.py: En este archivo se declaran las clases del modelo (ver ejemplos de descripción de

modelos en el apéndice B).

views.py: En este archivo se declaran las funciones de la vista.

En el apéndice B encontrará un listado con la definición de los modelos de datos y en el apéndice C

encontrará una impresión de las plantillas de captura de cada una de las aplicaciones descritas

anteriormente.

La estructura de directorios archivos del proyecto SIAA se veía como se muestra el diagrama 3.1.

SIAA

o Académicos

admin.py

__init__.py

models.py

views.py

o Distinciones

admin.py

__init__.py

models.py

views.py

o Divulgación

admin.py

__init__.py

models.py

views.py

o Docencia

admin.py

__init__.py

models.py

views.py

o Intercambio

admin.py

__init__.py

models.py

views.py

o Investigación

admin.py

__init__.py

models.py

views.py

o Proyectos

admin.py

__init__.py

models.py

views.py

o Vinculación

admin.py

Page 8: Desarrollo e implementación del Sistema de Información ...

8

__init__.py

models.py

views.py

o Generales

admin.py

__init__.py

models.py

views.py

__init__py manage.py settings.py urls.py

Diagrama 3.1 Estructura jerárquica del proyecto SIAA en Django.

3.3 El modelo de datos

Un modelo es la representación de la base de datos y sus tablas en forma de clases. Contiene los campos

básicos y el comportamiento de los datos que serán almacenados. Por lo general, cada modelo se convierte

en una tabla de la base de datos.

Cada módulo o sección cuenta con un archivo models.py, en este se definen cada uno de los modelos o

tablas que contendrá nuestra base de datos. El comportamiento de estos datos se define mediante la

definición de funciones o métodos en cada una de las clases que hemos definido para cada uno de los

modelos que serán utilizados. En el apéndice B se encuentra el código de los modelos definidos en cada

aplicación.

Cada modelo es una subclase de django.db.models.Model, heredando todas las funciones ya

implementadas en el framework, que son básicamente todo lo referente al acceso a la base de datos y el

tratamiento de los datos que maneja el modelo.

Por otra parte cada uno de los atributos que definimos en nuestro modelo, representa un atributo en la

tabla que el modelo genera. En la documentación oficial de Django se puede encontrar una amplia

definición de los tipos de campos que pueden ser usados en los atributos.

El framework de django nos proporciona acceso automático a la base de datos sin necesidad de programar

rutinas extras, otra de las características es que desde el momento que se crea el modelo de datos, no se

tiene que programar código en SQL: todos los cambios y acciones que se necesite realizar en la estructura

de los modelos se realizará en lenguaje python tratando cada tabla como un objeto. El framework se

encargará de manera automática de generar todo el código SQL para crear las tablas y realizar las

diferentes consultas que se requieran.

3.4 Las vistas

Un función de vista o una vista, es una función en Python que hace una solicitud Web y devuelve una

respuesta Web, esta respuesta puede ser el contenido de una página, un error 404, una imagen, un

documento XML, HTML, PDF entre otros.

Page 9: Desarrollo e implementación del Sistema de Información ...

9

La vista contiene toda la lógica necesaria para devolver una respuesta, todas estas respuestas se

encuentran en un único archivo y este archivo se llama: views.py, que se encuentra dentro de cada

aplicación de Django.

En el apéndice A se localiza el ejemplo de la vista para generar el reporte en PDF de un informe anual.

3.5 Las plantillas o templates

Django posee un componente conocido como “el motor de plantillas”, este motor brinda un poderoso

mini-lenguaje para definir detalles de la capa de la aplicación, que visualiza el usuario. Esto refuerza la

separación de la lógica de programación y la lógica de presentación.

Las plantillas pueden ser desarrolladas y mantenidas por cualquier persona con un poco de conocimiento

de HTML y lógica común. No necesita fundamentos de Python. En el apéndice D encontrá el ejemplo de

las plantillas utilizadas en el SIAA Para mostrar un informe anual.

4 PARTE 2: EL SIAA COMO APLICACIÓN EN DJANGO.

Como ya se mencionó en el apartado 1.2, el SIAA cuenta con varias secciones o módulos que interactúan

entre ellos para obtener y procesar la información que los investigadores capturan, hecho esto, poder

mostrarla a manera de informe anual o por áreas.

Para un mejor entendimiento en el documento llamaremos módulos a cada una de las aplicaciones que

conforman el proyecto del SIAA. Así, tenemos que el SIAA se compone de 10 módulos; 8 son para captura

y consulta de información de los investigadores y 2 para administración de SIAA. En el diagrama 4.1 se

muestra una estructura colaborativa de los módulos.

Page 10: Desarrollo e implementación del Sistema de Información ...

1

0

Diagrama 4.1. Módulos del SIAA.

Cada uno de los módulos es un administrador de la tabla correspondiente en la base de datos. Dado que el

framework proporciona un acceso automático a la base de datos, una vez que se definen los modelos y se

crean las tablas en la base de datos, cada módulo tiene acceso a ellas para realizar las consultas que se

requieran. Entiéndase por consultas a las acciones como añadir registros, modificarlos o listarlos. En la

figura 2.1 se muestran los módulos mencionados en el SIAA.

4.1 Crear y modificar los módulos del SIAA.

El SIAA, es una aplicación modular desarrollada bajo el modelo MVC, permite la modificación e

integración y de nuevos módulos de manera relativamente simple.

Antes de realizar algún cambio en el SIAA o cualquier sistema desarrollado con el framework Django, es

muy importante leer la documentación oficial de la versión en que ha sido desarrollado la cual se especifica

en el primer capítulo de este reporte. Es muy importante tener un respaldo de la aplicación y la base de

datos.

Agregar un módulo nuevo

1. Acceder al servidor de django, ir al directorio donde se almacena nuestro proyecto y ejecutar el

siguiente comando:

python manage.py startapp <<nombre del módulo>>

Page 11: Desarrollo e implementación del Sistema de Información ...

1

1

El comando anterior creará las instancias para el nuevo módulo, las cuales son: un directorio con el nombre

del módulo el cual se asigna por medio del comando y dentro de este los archivos __init__.py, models.py,

views.py de los cuales se ha hablado en el apartado 3.2.

2. El siguiente paso es definir nuestro modelo de datos dentro del archivo models.py, esencialmente

definimos la base de datos, campos y algunos metadatos por medio de clases. El en apartado 3.3

hablamos del modelo de datos y en el apéndice B se pueden consultar los ejemplos de la definición

de los modelos de datos de los módulos que integran el SIAA.

3. Hecho lo anterior es necesario activar nuestro nuevo módulo, para hacerlo se debe editar el archivo

settings.py y cambiar el parámetro INSTALLED_APPS para incluir la cadena “siaa.<<nombre del

módulo>>”. En el apéndice A.1 se puede revisar el contenido del archivo settings.py del SIAA.

4. Finalizamos la integración del nuevo módulo ejecutando el siguiente comando, nuevamente

ubicándonos en el directorio principal del proyecto SIAA.

python manage.py syncdb

El comando syncdb ejecuta el sql de “sqlall” en tu base de datos para todas los módulos definidos en

INSTALLED_APPS que no existían ya en la base de datos. Esto crea todas las tablas, los datos iniciales

y los índices para cada módulo que se haya agregado al proyecto desde la última vez que se ejecutó syncdb.

syncdb puede ser ejecutado tan frecuentemente como se desee, y sólo creará las tablas que no existan.

Modificar un módulo existente

El proceso para modificar un módulo ya integrado en el SIAA en completamente manual. Ya que el

comando python manage.py syncdb solo crea las tablas que no existen, este no servirá para realizar

cambios o eliminar tablas o campos que deseamos que desaparezcan.

Para modificar un módulo debemos considerar primero realizar los cambios en la definición del modelo

en el archivo models.py. Cada uno de los cambios realizados en el modelo (cambio de tipo de datos,

agregar campos, eliminación de campos, eliminar tablas, etc.), debemos realizarlo dentro de la base de

datos de forma manual. Para esta tarea podemos ayudarnos de un manejador de base de datos (DBMS por

sus siglas en inglés), de tal forma que nos permita acceder a la estructura física de nuestra base de datos.

Page 12: Desarrollo e implementación del Sistema de Información ...

1

2

Imagen 4.1. Captura de pantalla del SIAA donde se muestran algunos de los módulos que integran el sistema.

4.2 Crear y modificar los módulos del SIAA.

Como se describió en la sección 3.2 cada módulo almacena una determinada información que después

podrá ser consultada en el sistema o a manera de reporte.

Cada uno de los módulos del SIAA tiene una conexión con el módulo de usuarios del sistema. La finalidad

de este vínculo es poder determinar la pertenencia de los datos almacenados, permitiendo la elaboración

de reportes personalizados. En el diagrama 4.2 se pueden observar las relaciones.

Page 13: Desarrollo e implementación del Sistema de Información ...

1

3

La relación entre el módulo de usuarios y el de académicos, principalmente entre la entidad o modelo de

datos generales, proporciona información adicional del académico.

Cada usuario podrá ingresar a aquellos módulos a los que tenga acceso y de esta manera ir añadiendo la

información requerida en cada una de las secciones de estos módulos. Así con la relación existente entre

el módulo que se está modificando y el de usuarios del sistema, se conocerá exactamente a quién pertenece

un nuevo registro, que registros puede modificar y qué registros deben ser devueltos en la consulta de cada

usuario.

Si bien cada sección es creada como una tabla por separado, es la definición de nuestro modelo, descrito

en el apartado 3.2, quien se encarga de agruparlas en cada módulo. Y es la relación entre el usuario y cada

una de los modelos que permite reunir y acotar una consulta.

El módulo de datos generales y cada una de sus entidades, provee a los demás módulos del SIAA, de

información para los campos de selección múltiple principalmente. De esta forma se provee a los

usuarios de un mecanismo de prellenado de información, reduciendo la variación de la información para

campos específicos.

Diagrama 4.2. Esquema de interacción entre los módulos del SIAA.

Page 14: Desarrollo e implementación del Sistema de Información ...

1

4

4.3 Crear y modificar los módulos del SIAA.

Dada la naturaleza de las bases de datos, toda la información que se captura en cada uno de los módulos

se almacena en la misma tabla, por lo que es necesario tener un mecanismo de asignación de la información

al usuario que la está ingresando y del periodo correspondiente.

Para hacer la clasificación de la información por usuario y periodo de reporte, primero se obtiene la

información del usuario conectado, la cual se almacena en un atributo de control llamado propietario (ver

segmento de código 4.1). Así mismo se obtiene la fecha actual y se calcula el periodo en el que se

encuentra dentro del método save de la clase del modelo y en los atributos de control (ver segmento de

código 4.1). Se determinó que los periodos de informe estarían contemplados entre el 1 de febrero del año

en curso y el 31 de enero del año siguiente, con la finalidad de dar oportunidad a los usuarios de terminar

su llenado de datos en una fecha límite aproximada de mediados del mes de enero del año siguiente a la

fecha de reporte de actividades. En el apéndice B, se encuentran los códigos completos de la definición

de los modelos de cada módulo.

class NombreDelModelo(models.Model): #Atributos del modelo que se convertirán en campos de la tabla.

#Este es un modelo explicativo, en esta área se colocan todos los atributos

correspondientes al modelo #Atributos de control propietario = models.ForeignKey(User) fecha_c = models.DateField() fecha_m = models.DateField() year_c = models.IntegerField('Año de reporte', editable=False) def save(self, *args, **kwargs):

if not self.id: self.fecha_c = datetime.datetime.today() if datetime.datetime.today().month == 01: self.year_c = datetime.datetime.today().year-1 else: self.year_c = datetime.datetime.today().year self.fecha_m = datetime.datetime.today() super(NombreDelModelo, self).save(*args, **kwargs)

Segmento de código 4.1. Ejemplo explicativo de la definición de un modelos de datos en Python, con los correspondientes

campos de control para definir el propietario, fecha de creación, fecha de modificación y año de reporte al que corresponde.

Todos los modelos definidos en cada una de las aplicaciones que componen el sistema SIAA a excepción

de los módulos de administración efectúan el proceso de clasificación de datos descrito anteriormente.

Así, cada que los datos son consultados, primero se realiza una comprobación de usuario. Si se trata de un

superusuario o administrador, serán devueltos todos los datos; de lo contrario, sólo se devuelven los datos

que corresponden al usuario. La forma como se realiza la recuperación de datos se muestra en el segmento

de código 4.2. Estas funciones están definidas en los archivos admin.py, en el apéndice B se muestra el

código completo de estos archivos.

def queryset(self, request): qs = super(ModeloDeDatosAdmin, self).queryset(request)

Page 15: Desarrollo e implementación del Sistema de Información ...

1

5

#Si el usuario no es un superusuario o administrador, filtrará los contenidos y

solo mostrara lo que el usuario ha creado if not request.user.is_superuser and not request.user.groups.filter(id=2): qs = qs.filter(propietario = request.user) return qs def changelist_view(self, request, extra_context=None): #Si el mes actual es enero, se seguirán mostrando los elementos del año anterior if datetime.datetime.today().month == 1: YEAR = datetime.datetime.today().year - 1 else: YEAR = datetime.datetime.today().year if not request.GET.has_key('year_c'): q = request.GET.copy() q['year_c'] = YEAR request.GET = q request.META['QUERY_STRING'] = request.GET.urlencode() return super(ModeloDeDatosAdmin,self).changelist_view(request,

extra_context=extra_context) Segmento de código 4.2. Métodos de la clase Admin de los modelos del SIAA utilizados para hacer el filtrado de información

a recuperar por usuario y fecha de reporte.

De esta manera nos aseguramos que los usuarios solo vean la información que les pertenece, evitando

así que sean modificados datos de forma arbitraria. En la imagen 4.2 se muestra un ejemplo de

visualización de datos filtrada por permisos de usuario.

Page 16: Desarrollo e implementación del Sistema de Información ...

1

6

Imagen 4.2. Filtrado de datos por tipo de usuario. Arriba, captura de pantalla del SIAA ingresando como administrador.

Abajo, captura de pantalla del SIAA ingresando como un usuario

Page 17: Desarrollo e implementación del Sistema de Información ...

1

7

4.4 Crear y modificar los módulos del SIAA.

Con los datos almacenados en el SIAA se pueden generar distintos reportes. En la versión actual del

sistema, los reportes generales son los informes de actividades. Se puede generar un reporte como usuario

o administrador. Un usuario tendrá la posibilidad de generar el reporte de sus datos y elegir el año que

desea reportar. Un administrador tiene la posibilidad de elegir el usuario y el año del cual desea visualizar

un reporte.

Cuando un usuario o administrador solicita un reporte al SIAA, se lleva a cabo la ejecución de la función

reporting la cual esta almacenada en el archivo views.py del proyecto SIAA. El archivo views.py y las

funciones que lo integran pueden consultarse en el apéndice A.

La función reporting, realiza una consulta a cada una de las tablas, tomando en cuenta el periodo solicitado

y el usuario que hizo la requisición. Toda esta información queda almacenada una variable general que

será enviada a un template para que sea interpretada y mostrada al usuario de acuerdo al formato solicitado

(HTML, PDF, TXT). En especial para la generación de un PDF, SIAA hace uso de la librería de Python

PISA. El proceso anterior se ilustra en el diagrama 4.3.

Diagrama 4.3. Proceso de petición de un reporte en el SIAA.

Page 18: Desarrollo e implementación del Sistema de Información ...

1

8

Para la obtención de un reporte, se accede desde el icono ubicado en la parte derecha de la ventana

principal del SIAA, como se ilustra en la imagen 4.3.

Imagen 4.3. Enlace para acceder a la sección de reportes/Informes en el SIAA.

Una vez que se accede a esta sección, tanto usuarios como administradores tienen la posibilidad de

visualizar el reporte en tres formatos distintos como se muestra en la imagen 4.4:

Vista preliminar, la cual nos permite dar un vistazo dentro del mismo SIAA en formato HTML.

En esta forma de visualización las secciones que no no hayan sido llenadas con información o que

no exista, serán marcadas con un mensaje que informará al usuario de la ausencia de información

como se muestra en la imagen 2.4.

Formato PDF, este en un formato para descargar el informe como evidencia física y para hacer

la entrega del mismo a la dirección del centro.

Formato Texto, esta función permite obtener la información del reporte en formato de texto plano,

es útil para casos en los que se necesita copiar y pegar información o para convertirlo en algún

otro formato.

Page 19: Desarrollo e implementación del Sistema de Información ...

1

9

Imagen 4.4. Captura de pantalla de la sección reportes del SIAA.

Page 20: Desarrollo e implementación del Sistema de Información ...

2

0

4.5 Crear y modificar los módulos del SIAA.

Con las primeras pruebas del sistema, los usuarios hicieron llegar sus comentarios sobre la experiencia.

De esta retroalimentación surgieron algunas funciones que fueron integradas al SIAA a manera de

funciones auxiliares, estas funciones no forman la estructura primaria del sistema, pero ayudan al usuario

a mejorar la experiencia de su uso.

Duplicar registros Esta función permite realizar una copia de alguno de los registros existentes en alguna de las secciones de

los módulos que integran el SIAA. Como se muestra en la imagen 4.5, el usuario selecciona los elementos

que desea duplicar, abre el menú desplegable de acciones que se encuentra en la parte superior del listado

de registros. Elige la opción duplicar y al instante tiene uno o varios registros duplicados. Esta función no

solo duplica el registro sino que actualiza la fecha de creación, permitiendo de esta manera obtener un

registro de un año anterior en un reporte de año nuevo.

Por ejemplo: Se tiene una serie de artículos en proceso de arbitraje, y al año siguiente fueron aceptados,

de esta manera el usuario solo tendrá que duplicar los artículos registrados el año anterior y actualizar el

estatus de los mismos.

Otro ejemplo de aplicación de esta función sería: La participación periódica en determinado evento, donde

la mayoría de los datos descriptivos son los mismos, siendo solo necesario cambiar una fecha o un mínimo

de datos.

Imagen 4.5. Duplicar un registro.

Filtros de información La función de filtros permite a los usuarios visualizar sólo la información relevante de acuerdo al campo

que se le aplique el filtro. Para evitar la saturación de filtros, se definió a los usuarios la posibilidad de

filtrar por año, en algunos casos por algún otro campo. En el caso de los administradores la lista de campos

incluidos en los filtros es más amplia, esto ayuda para obtener información relevante que es reportada al

CTIC. En la figura 4.6 se muestra un ejemplo del uso de filtros.

Page 21: Desarrollo e implementación del Sistema de Información ...

2

1

Imagen 4.6. Uso de filtros por año en registros del SIAA.

Historial de acciones y cambios. Los historiales de registros permiten a los usuarios monitorear sus últimas acciones, así como poder

consultar quién creó o modificó sus registros. En la figura 4.7 y 4.8 se muestran ejemplos de estas

funciones y cómo localizarlos.

Imagen 4.7. Historial de acciones recientes en el SIAA.

Page 22: Desarrollo e implementación del Sistema de Información ...

2

2

Imagen 2.8. Arriba, Ubicación del botón para acceder al historial de cambios de un registro. Abajo, Ejemplo de un historial

de cambios de un registro.

5 COMENTARIOS FINALES

El SIAA hasta la fecha en que este reporte se escribió se encuentra funcionando en la versión 1.4 de

manera estable. Se considera una versión beta debido a su naturaleza web y a su arquitectura, no deja de

ser beta ya que se encuentra abierta a cambios y adaptaciones de acuerdo a las necesidades que surjan en

el centro. Así mismo el SIAA puede fácilmente incluir nuevos módulos de áreas que decidan integrar su

reporte de datos.

Cabe aclarar que el SIAA está disponible de forma gratuita para ser implementado en otros centros,

institutos y facultades, previa petición del director de la dependencia interesada, al director del CRyA.

Page 23: Desarrollo e implementación del Sistema de Información ...

2

3

APÉNDICE A. ARCHIVOS BÁSICOS DE UN PROYECTO EN DJANGO PARA EL

SIAA.

A.1 Código fuente del archivo settings.py #! /usr/bin/python # -*- coding: utf-8 -*- # Django settings for siaa project. import os SITE_ROOT_DIR= os.path.dirname(os.path.realpath(__file__)) #DEBUG = True DEBUG = True TEMPLATE_DEBUG = DEBUG ADMINS = ( ('Leonardo', '[email protected]'), ) MANAGERS = ADMINS DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or

'oracle'. 'NAME': 'siaa', # Or path to database file if using sqlite3. 'USER': 'cryaweb', # Not used with sqlite3. 'PASSWORD': 'db4s3.cry4', # Not used with sqlite3. 'HOST': '', # Set to empty string for localhost. Not used with sqlite3. 'PORT': '', # Set to empty string for default. Not used with sqlite3. 'OPTIONS': { "init_command": "SET foreign_key_checks = 0;", }, } } # Reordenamiento de Apps y Modelos ADMIN_REORDER = ( ('Academicos',('Datos generales (Investigador)','Datos generales (Posdoctorado)','Datos generales (Técnico

Académico)','Información adicional para el reporte')), ('Distinciones',('Premios que has recibido en el año','Premios otorgados a tus alumnos dirigidos en el año')), ('Divulgacion', ('Presentaciones en eventos', 'Eventos Organizados', 'Artículos de divulgación', 'Producciones

editoriales', 'Entrevistas', 'Producción de programas (Radio, TV e Internet)')), ('Docencia',('Comites tutorales','Alumnos','Asesoría de trabajos escritos','Asesorias externas','Cursos

regulares (Licenciatura UNAM)','Cursos regulares (Posgrado UNAM)','*Cursos regulares (Posgrado UNAM)','Cursos externos

(Licenciatura)','Cursos externos (Posgrado)','Cursos únicos')), ('Intercambio',()), ('Investigacion',()), ('Proyectos',('Convenios', 'Proyectos administrados por el CRyA (Participación)', 'Proyectos administrados por

el CRyA (Responsable)', 'Proyectos de observación', 'Proyectos de supercómputo')), ('Vinculacion',('Arbitrajes de proyectos','Arbitrajes en revistas', 'Asesorías', 'Asistencia y Presentaciones

en eventos académicos', 'Organización de eventos académicos', 'Superación Académica')), ('Generales',()), ('Auth', ('Usuarios','Grupos')), ) # Local time zone for this installation. Choices can be found here: # http://en.wikipedia.org/wiki/List_of_tz_zones_by_name # although not all choices may be available on all operating systems. # On Unix systems, a value of None will cause Django to use the same # timezone as the operating system. # If running in a Windows environment this must be set to the same as your # system time zone. TIME_ZONE = 'America/Chicago' # Language code for this installation. All choices can be found here: # http://www.i18nguy.com/unicode/language-identifiers.html LANGUAGE_CODE = 'es-mx' SITE_ID = 1

Page 24: Desarrollo e implementación del Sistema de Información ...

2

4

# If you set this to False, Django will make some optimizations so as not # to load the internationalization machinery. USE_I18N = True # If you set this to False, Django will not format dates, numbers and # calendars according to the current locale USE_L10N = True #USE_L10N = False #DATE_FORMAT = 'd/m/Y' #DATETIME_FORMAT = 'd/m/Y H:i'

# Absolute filesystem path to the directory that will hold user-uploaded files. # Example: "/home/media/media.lawrence.com/media/" MEDIA_ROOT = os.path.join(SITE_ROOT_DIR, 'media') # URL that handles the media served from MEDIA_ROOT. Make sure to use a # trailing slash. # Examples: "http://media.lawrence.com/media/", "http://example.com/media/" MEDIA_URL = 'http://www.crya.unam.mx:8000/media/' # Absolute path to the directory static files should be collected to. # Don't put anything in this directory yourself; store your static files # in apps' "static/" subdirectories and in STATICFILES_DIRS. # Example: "/home/media/media.lawrence.com/static/" STATIC_ROOT = os.path.join(SITE_ROOT_DIR,'static') # URL prefix for static files. # Example: "http://media.lawrence.com/static/" STATIC_URL = 'http://www.crya.unam.mx:8000/static/' # URL prefix for admin static files -- CSS, JavaScript and images. # Make sure to use a trailing slash. # Examples: "http://foo.com/static/admin/", "/static/admin/". ADMIN_MEDIA_PREFIX = '/static/admin/' # Additional locations of static files STATICFILES_DIRS = ( # Put strings here, like "/home/html/static" or "C:/www/django/static". # Always use forward slashes, even on Windows. # Don't forget to use absolute paths, not relative paths. ) # List of finder classes that know how to find static files in # various locations. STATICFILES_FINDERS = ( 'django.contrib.staticfiles.finders.FileSystemFinder', 'django.contrib.staticfiles.finders.AppDirectoriesFinder', # 'django.contrib.staticfiles.finders.DefaultStorageFinder', ) # Make this unique, and don't share it with anybody. SECRET_KEY = '&qlq$f)5bt$=90co0w1jcvlpg_0cjtf89!bcmg%akihu2w$wsb' # List of callables that know how to import templates from various sources. TEMPLATE_LOADERS = ( 'django.template.loaders.filesystem.Loader', 'django.template.loaders.app_directories.Loader', # 'django.template.loaders.eggs.Loader', ) MIDDLEWARE_CLASSES = ( 'django.middleware.common.CommonMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', ) ROOT_URLCONF = 'siaa.urls' TEMPLATE_DIRS = (

Page 25: Desarrollo e implementación del Sistema de Información ...

2

5

# Put strings here, like "/home/html/django_templates" or "C:/www/django/templates". # Always use forward slashes, even on Windows. # Don't forget to use absolute paths, not relative paths. os.path.join(SITE_ROOT_DIR, 'media/templates') #'/http/root/djcode/siaa/media/templates/', )

INSTALLED_APPS = ( 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', #'django.contrib.sites', 'django.contrib.messages', 'django.contrib.staticfiles', # Uncomment the next line to enable the admin: 'django.contrib.admin', # Uncomment the next line to enable admin documentation: #'django.contrib.admindocs', # Smart-Selects #'smart_selects', # ---- #'django_tables2', # Aplicaciones creadas para el Proyecto SIAA 'siaa.academicos', 'siaa.generales', 'siaa.vinculacion', 'siaa.divulgacion', 'siaa.investigacion', 'siaa.docencia', 'siaa.distinciones', 'siaa.proyectos', #'globaltags' 'siaa.intercambio' #'polls', ) AUTHENTICATION_BACKENDS = ( 'django.contrib.auth.backends.ModelBackend', 'backend.loginIMAP', ) # A sample logging configuration. The only tangible logging # performed by this configuration is to send an email to # the site admins on every HTTP 500 error. # See http://docs.djangoproject.com/en/dev/topics/logging for # more details on how to customize your logging configuration. import sys LOGGING = { 'version': 1, 'disable_existing_loggers': True, 'formatters': { 'standard': { 'format' : "[%(asctime)s] %(levelname)s [%(name)s:%(lineno)s] %(message)s", 'datefmt' : "%d/%b/%Y %H:%M:%S" }, }, 'handlers': { 'null': { 'level':'DEBUG', 'class':'django.utils.log.NullHandler', }, 'logfile': { 'level':'DEBUG', 'class':'logging.handlers.RotatingFileHandler', 'filename': '/http/root/djcode/logfile.log', 'maxBytes': 50000, 'backupCount': 2, 'formatter': 'standard', }, 'console':{ 'level':'INFO', 'class':'logging.StreamHandler', 'formatter': 'standard', }, }, 'loggers': { 'django': { 'handlers':['console'],

Page 26: Desarrollo e implementación del Sistema de Información ...

2

6

'propagate': True, 'level':'WARN', }, 'django.db.backends': { 'handlers': ['console'], 'level': 'DEBUG', 'propagate': False, }, 'MYAPP': { 'handlers': ['console', 'logfile'], 'level': 'DEBUG', }, } } # Variables definidas LOGIN_REDIRECT_URL='/siaa'

5.1 A3. Código fuente del archivo urls.py #! /usr/bin/python # -*- coding: utf-8 -*- from django.conf.urls.defaults import patterns, include, url from siaa.academicos.views import * from siaa.views import * from django.contrib import admin admin.autodiscover() urlpatterns = patterns('', #Todas las vistas definidas para el proyecto url(r'^admin/siaa/report/$', reporting), #Lograr que se visualicen imagenes, js, css. (r'^media/(?P<path>.*)$', 'django.views.static.serve',{'document_root': settings.MEDIA_ROOT}), # static content url(r'^login/$', 'django.contrib.auth.views.login' ), url(r'^logout/$', 'django.contrib.auth.views.logout'), #url(r'^chaining/', include('smart_selects.urls')), #chained-select # MANTENER ESTAS VISTAS SIEMPRE AL FINAL DEL ARCHIVO # Uncomment the next line to enable the admin: url(r'^admin/', include(admin.site.urls),), )

5.2 A.2 Código feunte del archivo views.py #! /usr/bin/python # -*- coding: utf-8 -*- import datetime import cStringIO as StringIO import ho.pisa as pisa import cgi from django.template import RequestContext from django.template.loader import render_to_string from django.http import HttpResponse from django.template.loader import get_template from django.template import Context import datetime from siaa.functions import *

if datetime.datetime.today().month == 1: YEAR = int(datetime.datetime.today().year)-1 # Se obtiene el año actual else: YEAR = int(datetime.datetime.today().year) def generar_pdf(template_src, context_dict): # Función para generar el archivo PDF y devolverlo mediante HttpResponse template = get_template(template_src) context = Context(context_dict) html = template.render(context) filename = context_dict['filename'] result = StringIO.StringIO() #pdf = pisa.pisaDocument(StringIO.StringIO(html.encode("ISO-8859-15")), result)

Page 27: Desarrollo e implementación del Sistema de Información ...

2

7

pdf = pisa.pisaDocument(StringIO.StringIO(html.encode("UTF-8")), result, encoding='UTF-8') if not pdf.err: response = HttpResponse(result.getvalue(), mimetype='application/pdf') return response return HttpResponse('Error al generar el PDF: %s' % cgi.escape(html))

def reporting(request): if request.GET.get('formato'): formato = request.GET.get('formato') else: formato = 'PRE' if request.GET.get('year'): year = int(request.GET.get('year')) else: year =YEAR if request.user.is_superuser or request.user.groups.filter(name='Administradores'): if request.GET.get('academico'): academicoID = int(request.GET.get('academico')) else: academicoID = 0 lista_academicos = get_academicos_all() academico = get_academicos(academicoID) else: academicoID = request.user.id academico = get_academicos(request.user.id) lista_academicos = [] todos_y = list(range(2012,YEAR+1)) to_pdf = {} context = { 'usuario':request.user, #Usuario actual 'lista_academicos':lista_academicos, #Lista de todos los academicos 'todos_y':todos_y, #Lista de años para reportar 'year':year, #Año de reporte 'YEAR':YEAR, #Año actual según el sistema 'academicoID':academicoID, #ID academico, enviado como parametro 'academico':academico, #Información del academico a reportar 'formato':formato, #Formato solicitado PRE/PDF/TXT } # App Info Adicional info_adicional = get_info_adicional(academicoID, year) if info_adicional: context['info']=info_adicional #Context info if info_adicional.info_adicional_es or info_adicional.info_adicional_en: to_pdf['info1']=True if info_adicional.info_otros: to_pdf['info2']=True if info_adicional.trabajo_inst: to_pdf['info3']=True if info_adicional.citas_t or info_adicional.citas_a: to_pdf['citas']=True # App Distinciones distinciones = get_distinciones(academicoID, year) if distinciones: to_pdf['dd'] = True context['distinciones']=distinciones #Context distinciones distinciones_alumno = get_distinciones_alumno(academicoID, year) if distinciones_alumno: to_pdf['da'] = True context['distinciones_a']=distinciones_alumno #Context distinciones_a if distinciones or distinciones_alumno: to_pdf['distinciones'] = True # App Divulgacion dv_produccion_e = get_DvProduccionE(academicoID, year) if dv_produccion_e: context['dv_produccion_e'] = dv_produccion_e to_pdf['ped']=True dv_eventos_o = get_DvOrganizacionEv(academicoID, year) if dv_eventos_o: context['dv_eventos_o'] = dv_eventos_o to_pdf['oe']=True dv_eventos_p = get_DvPresentacionEv(academicoID, year) if dv_eventos_p: context['dv_eventos_p'] = dv_eventos_p to_pdf['pe']=True dv_produccion_p = get_DvProduccionP(academicoID, year)

Page 28: Desarrollo e implementación del Sistema de Información ...

2

8

if dv_produccion_p: context['dv_produccion_p'] = dv_produccion_p to_pdf['prog']=True dv_entrevistas = get_DvEntrevistas(academicoID, year) if dv_entrevistas: context['dv_entrevistas'] = dv_entrevistas to_pdf['ent']=True dv_articulos = get_DvArticulos(academicoID, year) if dv_articulos: context['dv_articulos'] = dv_articulos to_pdf['adiv']=True if dv_produccion_e or dv_eventos_o or dv_eventos_p or dv_produccion_p or dv_entrevistas or dv_articulos: to_pdf['divulgacion'] = True # App Docencia dc_cursos_rl = get_cursosRL(academicoID, year) if dc_cursos_rl: context['dc_cursos_rl'] = dc_cursos_rl # to_pdf['crl']=True dc_cursos = get_cursosR() context['dc_cursos'] = dc_cursos # dc_cursos_d = get_cursosD(academicoID, year) if dc_cursos_d: context['dc_cursos_d'] = dc_cursos_d # to_pdf['crp']=True dc_cursos_el = get_cursosEL(academicoID, year) if dc_cursos_el: context['dc_cursos_el'] = dc_cursos_el # to_pdf['cel']=True dc_cursos_ep = get_cursosEP(academicoID, year) if dc_cursos_ep: context['dc_cursos_ep'] = dc_cursos_ep # to_pdf['cep']=True dc_cursos_u = get_cursosU(academicoID, year) if dc_cursos_u: context['dc_cursos_u'] = dc_cursos_u # to_pdf['cu']=True dc_ctutor = get_CTutor(academicoID, year) if dc_ctutor: context['dc_ctutor'] = dc_ctutor # to_pdf['ct']=True dc_tutorias = get_tutorias() context['dc_tutorias'] = dc_tutorias # dc_trabajos = get_trabajosEscritos(academicoID, year) if dc_trabajos: context['dc_trabajos'] = dc_trabajos # to_pdf['ate']=True dc_asesoria = get_asesoriaE (academicoID, year) if dc_asesoria: context['dc_asesoria'] = dc_asesoria # to_pdf['ae']=True dc_sinodal_et = get_sinodalET(academicoID, year) if dc_sinodal_et: context['dc_sinodal_et'] = dc_sinodal_et # to_pdf['set']=True dc_sinodal_egc = get_sinodalEGC(academicoID, year) if dc_sinodal_egc: context['dc_sinodal_egc'] = dc_sinodal_egc # to_pdf['segc']=True dc_sinodal_ec = get_sinodalEC(academicoID, year) if dc_sinodal_ec: context['dc_sinodal_ec'] = dc_sinodal_ec # to_pdf['sec']=True dc_sinodal_eg = get_sinodalEG(academicoID, year) if dc_sinodal_eg: context['dc_sinodal_eg'] = dc_sinodal_eg # to_pdf['seg']=True if dc_cursos_rl or dc_cursos_d or dc_cursos_el or dc_cursos_ep or dc_cursos_u or dc_ctutor or dc_trabajos or

dc_asesoria or dc_sinodal_et or dc_sinodal_eg or dc_sinodal_egc or dc_sinodal_ec: to_pdf['docencia']=True # App Intercambio i_visitas_i = get_visitasI(academicoID, year) if i_visitas_i: context['i_visitas_i'] = i_visitas_i # to_pdf['vi']=True i_visitas_n = get_visitasN(academicoID, year)

Page 29: Desarrollo e implementación del Sistema de Información ...

2

9

if i_visitas_n: context['i_visitas_n'] = i_visitas_n # to_pdf['vn']=True i_salidas_i = get_salidasI(academicoID, year) if i_salidas_i: context['i_salidas_i'] = i_salidas_i # to_pdf['ete']=True i_salidas_n = get_salidasN(academicoID, year) if i_salidas_n: context['i_salidas_n'] = i_salidas_n # to_pdf['etn']=True i_sabaticos = get_sabaticos (academicoID, year) if i_sabaticos: context['i_sabaticos'] = i_sabaticos # to_pdf['es']=True if i_visitas_i or i_visitas_n or i_salidas_i or i_salidas_n or i_sabaticos: to_pdf['intercambio']=True i_financiamiento = get_IFinanciamiento() context['i_financiamiento'] = i_financiamiento # # App Investigacion iv_articulos = get_IvArticulos(academicoID, year) if iv_articulos: context['iv_articulos'] = iv_articulos # to_pdf['ainv']=True iv_art_indices = get_IvArticulosIndices() context['iv_art_indices'] = iv_art_indices # iv_memorias = get_IvMemorias(academicoID, year) if iv_memorias: context['iv_memorias'] = iv_memorias # to_pdf['aem']=True iv_libros = get_IvLibros(academicoID, year) if iv_libros: context['iv_libros'] = iv_libros # to_pdf['le']=True iv_capitulos = get_IvCapitulos(academicoID, year) if iv_capitulos: context['iv_capitulos'] = iv_capitulos # to_pdf['cl']=True iv_reportes = get_IvReportes(academicoID, year) if iv_reportes: context['iv_reportes'] = iv_reportes # to_pdf['rt']=True iv_otros = get_IvOtros(academicoID, year) if iv_otros: context['iv_otros'] = iv_otros # to_pdf['or']=True iv_autores = get_IvAutores() context['iv_autores'] = iv_autores # iv_proyectos = get_IvProyectos() context['iv_proyectos'] = iv_proyectos # if iv_articulos or iv_memorias or iv_libros or iv_capitulos or iv_reportes or iv_otros: to_pdf['investigacion']=True # App Proyectos p_responsable = get_responsableP(academicoID, year) if p_responsable: context['p_responsable'] = p_responsable # to_pdf['pr']=True proyectos = get_proyectos() context['proyectos'] = proyectos # p_participacion = get_participacionP(academicoID, year) if p_participacion: context['p_participacion'] = p_participacion # to_pdf['pp']=True p_observaciones = get_observaciones(academicoID, year) if p_observaciones: context['p_observaciones'] = p_observaciones # to_pdf['po']=True p_scomputo = get_scomputo(academicoID, year) if p_scomputo: context['p_scomputo'] = p_scomputo # to_pdf['ps']=True p_internacionales = get_proyectosI(academicoID, year) if p_internacionales: context['p_internacionales'] = p_internacionales # to_pdf['pi']=True p_financiamiento = get_PFinanciamiento()

Page 30: Desarrollo e implementación del Sistema de Información ...

3

0

context['p_financiamiento'] = p_financiamiento # p_otrosrecursos = get_proyOtrosRecursos() context['p_otrosrecursos'] = p_otrosrecursos # p_convenios = get_convenios(academicoID, year) if p_convenios: context['p_convenios'] = p_convenios # to_pdf['c']=True if p_responsable or p_participacion or p_observaciones or p_scomputo or p_internacionales or p_convenios: to_pdf['proyectos']=True p_instituciones = get_institucionesConvenio() context['p_instituciones'] = p_instituciones # # App Vinculacion v_arbitraje = get_arbitraje(academicoID, year) if v_arbitraje: context['v_arbitraje'] = v_arbitraje # to_pdf['ar']=True v_arbitraje_p = get_arbitrajeP(academicoID, year) if v_arbitraje_p: context['v_arbitraje_p'] = v_arbitraje_p # to_pdf['ap']=True v_eventos_o = get_VOrganizacionEv(academicoID, year) if v_eventos_o: context['v_eventos_o'] = v_eventos_o # to_pdf['oea']=True v_eventos = get_eventosV(year) if v_eventos: context['v_eventos'] = v_eventos # to_pdf['eaa']=True v_presentaciones = get_presentacionesV(academicoID, year) if v_presentaciones: context['v_presentaciones'] = v_presentaciones # to_pdf['pea']=True """ v_eventos_p = get_VPresentacionEv(academicoID, year) if v_eventos_p: context['v_eventos_p'] = v_eventos_p # to_pdf['pea']=True """ v_servicios = get_servicios(academicoID, year) if v_servicios: context['v_servicios'] = v_servicios # to_pdf['serv']=True v_redes = get_redes(academicoID, year) if v_redes: context['v_redes'] = v_redes # to_pdf['redes']=True v_acad = get_acad (academicoID, year) if v_acad: context['v_acad'] = v_acad # to_pdf['sac']=True if v_arbitraje or v_arbitraje_p or v_eventos_o or v_eventos or v_presentaciones or v_servicios or v_redes or v_acad: to_pdf['vinculacion']=True context['to_pdf'] = to_pdf #Context to_pdf if formato == 'PRE': to_pdf = { 'academicos':True, 'info1':True, 'info2':True, 'info3':True, 'citas':True, 'distinciones':True, 'dd':True, 'da':True, 'divulgacion':True, 'pe':True, 'oe':True, 'adiv':True, 'ped':True, 'ent':True, 'prog':True, 'docencia':True, 'ct':True, 'ate':True, 'ae':True, 'crl':True, 'crp':True, 'cel':True, 'cep':True, 'cu':True,

'sec':True, 'seg':True, 'segc':True, 'set':True, 'intercambio':True, 'es':True, 'ete':True, 'etn':True, 'vi':True, 'vn':True, 'investigacion':True, 'ainv':True, 'aem':True, 'cl':True, 'le':True, 'or':True, 'rt':True, 'proyectos':True, 'c':True, 'pp':True, 'pr':True, 'po':True, 'ps':True, 'pi':True, 'vinculacion':True, 'ap':True, 'ar':True, 'as':True, 'oea':True, 'eaa':True, 'pea':True, 'redes':True,

'sac':True } context['to_pdf'] = to_pdf #Context to_pdf return render(request, 'reporte_preview.html',context) if formato == 'PDF': nom = academico.nombre.lower() nom += "-" nom += academico.apellido_p.lower() nom = nom.replace("\'","") nom = elimina_tilde(nom) context['filename'] = str(year)+"reporte_"+nom

Page 31: Desarrollo e implementación del Sistema de Información ...

3

1

context['pagesize'] = 'letter' context['signature'] = True html = render_to_string('siaa_pdf.html', {'pagesize':'letter'}, context_instance=RequestContext(request)) return generar_pdf('siaa_pdf.html',context) if formato == 'TXT': template = get_template("siaa_txt.html") nom = academico.nombre.lower() nom += "-" nom += academico.apellido_p.lower() nom = nom.replace("\'","") nom = elimina_tilde(nom) context['filename'] = str(year)+"reporte_"+nom context['pagesize'] = 'letter' context['signature'] = True template = get_template("siaa_txt.html") c = Context(context) response = HttpResponse(template.render(c), mimetype="text/plain")

return response

Page 32: Desarrollo e implementación del Sistema de Información ...

3

2

APÉNDICE B. DEFINICIÓN DE LOS MODELOS DE DATOS, CÓDIGO FUENTE DE LOS

ARCHIVOS MODELS.PY.

B.1 Modelos de datos de la aplicación académicos. #! /usr/bin/python # -*- coding: utf-8 -*- #------------------------------- # Modelos de la app academicos #------------------------------- #from django import forms from django.db import models from django.contrib.auth.models import User from django.core.validators import MaxLengthValidator from django.utils.translation import ugettext_lazy as _ from siaa.generales.models import * from django.db.models import Q import datetime SEXO=( ('M','Masculino'), ('F','Femenino'), ) TIPO_ACADEMICO = ( (1, 'Investigador'), (2, 'Posdoctorado'), (3, 'Técnico Académico'), ) class Academicos(models.Model): id = models.IntegerField(primary_key=True, unique=True) apellido_p = models.CharField('Apellido Paterno', max_length=20) apellido_m = models.CharField('Apellido Materno', max_length=20, blank=True) nombre = models.CharField('Nombre',max_length=30) username = models.ForeignKey (User, verbose_name='Usuario del sistema', related_name='FK_A_A_u', null=True,

blank=True) genero = models.CharField('Genero', max_length=1, choices=SEXO) fecha_nac = models.DateField('F. Nacimiento', null=True, blank=True) #edad = models.IntegerField('Edad', null=True, blank=True, editable=False) nombramiento = models.ForeignKey(Nombramiento, verbose_name='Tipo de Nombramiento', null=True, blank=True) escolaridad = models.ForeignKey(Escolaridad, verbose_name='Escolaridad', null=True, blank=True,

limit_choices_to=~Q(id=4)) nivel_sni = models.ForeignKey(NivelSNI, verbose_name='Nivel SNI', null=True, blank=True) nivel_pride = models.ForeignKey(NivelPRIDE, verbose_name='Nivel PRIDE', null=True, blank=True) fecha_pride = models.IntegerField('Año PRIDE', null=True, blank=True, help_text="Año de vencimiento del último

nombramiento PRIDE") tipo_contrato = models.ForeignKey(TipoContrato, verbose_name='Tipo de Contrato', null=True, blank=True) ingreso_unam = models.DateField('Fecha de ingreso a la UNAM',null=True, blank=True) tipo_academico = models.IntegerField(choices=TIPO_ACADEMICO, null=True, blank=True, default=1) #Datos para Posdocs nacionalidad = models.ForeignKey(Pais, verbose_name="Nacionalidad", null=True, blank=True) beca = models.CharField ('Becado por', max_length=100, null=True, blank=True, help_text="Nombre de la insticucion(es) que otroga la beca, en caso de ser más de una separar

con comas") fecha_inicio = models.DateField ('Inicio', null=True, blank=True) fecha_fin = models.DateField('Termino', null=True, blank=True) asesor = models.ForeignKey('self', verbose_name='Colabora con', null=True, blank=True, help_text='Nombre del colaborador o asesor (Investigador del

CRyA)', limit_choices_to=Q(tipo_academico=1)) t_articulos = models.IntegerField('Artículos publicados', help_text='Total de artículos publicados durante la

estancia', null=True, blank=True) class Meta: ordering = ['apellido_p', 'apellido_m', 'nombre'] db_table = 'Academicos' verbose_name ='Investigador' verbose_name_plural = 'Datos generales (Investigador)' def edad(self): if self.fecha_nac: if datetime.date.today().month < self.fecha_nac.month:

Page 33: Desarrollo e implementación del Sistema de Información ...

3

3

td = (datetime.date.today().year - self.fecha_nac.year)-1 else: td = datetime.date.today().year - self.fecha_nac.year return td else: return None def antiguedad(self): if self.ingreso_unam: if datetime.date.today().month < self.ingreso_unam.month: td = (datetime.date.today().year - self.ingreso_unam.year)-1 else: td = datetime.date.today().year - self.ingreso_unam.year return td else: return None def __unicode__(self): return self.apellido_p+", "+self.nombre def some_name(self): return '<a href="/some/admin/url/here/%s/">Link Name</a>' % self.id some_name.allow_tags = True #this is to allow HTML tags. some_name.short_description = 'Table Header Name here' class TAcademico(Academicos): class Meta: proxy=True ordering = ['apellido_p', 'apellido_m', 'nombre'] verbose_name ='Técnico Académico' verbose_name_plural = 'Datos generales (Técnico Académico)' class Posdocs(Academicos): class Meta: proxy=True ordering = ['apellido_p', 'apellido_m', 'nombre'] verbose_name ='Posdoctorado' verbose_name_plural = 'Datos generales (Posdoctorado)' class ReporteInfo(models.Model): info_adicional_es = models.TextField('Resultados más destacados en la investigación durante el año (Español)',

null=True, blank=True, help_text=TEXTO1, validators=[MaxLengthValidator(1500)]) info_adicional_en = models.TextField('Resultados más destacados en la investigación durante el año (Inglés)',

null=True, blank=True, help_text=TEXTO2, validators=[MaxLengthValidator(1500)]) trabajo_inst = models.TextField('Trabajo institucional que realizaste durante año', null=True, blank=True,

help_text=TEXTO3, validators=[MaxLengthValidator(1000)]) info_otros = models.TextField('Acontecimientos relevantes y logros destacados (No investigación)', null=True,

blank=True, help_text=TEXTO4, validators=[MaxLengthValidator(800)]) citas_a = models.IntegerField ('Citas en el año', default=0, null=True, blank=True, help_text='Número de citas

en el año',) citas_t = models.IntegerField ('Total de citas', default=0, null=True, blank=True, help_text='Número total de

citas acumulado durante la carrera',) #Campos de control ---> propietario = models.ForeignKey(User, null=True, blank=True, verbose_name="Académico", related_name='A_A_RI') fecha_c = models.DateField('Fecha de creación',editable=False, null=True, blank=True) fecha_m = models.DateField('Última modificación', null=True, blank=True) year_c = models.IntegerField('Año de reporte', editable=False, null=True, blank=True) class Meta: ordering= ['propietario'] verbose_name='Información' verbose_name_plural='Información adicional para el reporte' def __unicode__(self): return u'%s, %s' % (self.propietario.last_name, self.propietario.first_name) def save(self, *args, **kwargs): if not self.id: self.fecha_c = datetime.datetime.today() if datetime.datetime.today().month == 01: self.year_c = datetime.datetime.today().year-1 else: self.year_c = datetime.datetime.today().year self.fecha_m = datetime.datetime.today() super(ReporteInfo, self).save(*args, **kwargs)

Page 34: Desarrollo e implementación del Sistema de Información ...

3

4

5.3 B.2 Modelos de datos de la aplicación distinciones. #! /usr/bin/python # -*- coding: utf-8 -*- #------------------------------------ # Modelos de la app distinciones #------------------------------------ from django.db import models from django.contrib.auth.models import User from django.db.models import Q from siaa.generales.models import TipoPremio, Pais, Ambito, Escolaridad import datetime class OtorgadosAcademicos(models.Model): nom_premio = models.CharField('Nombre del premio o distinción', max_length=100) tipo_premio = models.ForeignKey(TipoPremio, verbose_name='Tipo de premio') pais_inst = models.ForeignKey(Pais, verbose_name='Pais', default=159) nom_inst = models.CharField('Nombre de la institución', max_length=200) ambito = models.ForeignKey(Ambito, verbose_name='Ambito', limit_choices_to = ~Q(id=5)) fecha = models.DateField('Fecha', help_text='Fecha en que se recibió el reconocimiento') #Campos de control ---> propietario = models.ForeignKey(User, null=True, blank=True, verbose_name="Académico", related_name='D_OA_p') fecha_c = models.DateField(editable=False, null=True, blank=True) fecha_m = models.DateField(null=True, blank=True) year_c = models.IntegerField('Año de reporte', editable=False, null=True, blank=True) class Meta: ordering= ['propietario','tipo_premio','nom_premio'] verbose_name='Premio recibido' verbose_name_plural='Premios que has recibido en el año' def __unicode__(self): return self.nom_premio def save(self, *args, **kwargs): if not self.id: self.fecha_c = datetime.datetime.today() if datetime.datetime.today().month == 01: self.year_c = datetime.datetime.today().year-1 else: self.year_c = datetime.datetime.today().year self.fecha_m = datetime.datetime.today() super(OtorgadosAcademicos, self).save(*args, **kwargs) class OtorgadosAlumnos(models.Model): nom_premio = models.CharField('Nombre del premio o distinción', max_length=100) nom_premiado = models.CharField('Nombre del alumno', max_length=100) escolaridad = models.ForeignKey(Escolaridad, verbose_name='Nivel de estudios', limit_choices_to =

Q(id=2)|Q(id=5)|Q(id=7)) pais_inst = models.ForeignKey(Pais, verbose_name='Pais', default=159) nom_inst = models.CharField('Nombre de la institución', max_length=200) ambito = models.ForeignKey(Ambito, verbose_name='Ambito', limit_choices_to = ~Q(id=5)) fecha = models.DateField('Fecha', help_text='Fecha en que se recibió el reconocimiento') #Campos de control ---> propietario = models.ForeignKey(User, null=True, blank=True, verbose_name="Académico", related_name='D_OAl_p') fecha_c = models.DateField(editable=False, null=True, blank=True) fecha_m = models.DateField(null=True, blank=True) year_c = models.IntegerField('Año de reporte', editable=False, null=True, blank=True) class Meta: ordering= ['propietario','nom_premiado','nom_premio'] verbose_name='Premio otorgado a tu alumno dirigido' verbose_name_plural='Premios otorgados a tus alumnos dirigidos en el año' def __unicode__(self): return self.nom_premio def save(self, *args, **kwargs): if not self.id: self.fecha_c = datetime.datetime.today() if datetime.datetime.today().month == 01: self.year_c = datetime.datetime.today().year-1

Page 35: Desarrollo e implementación del Sistema de Información ...

3

5

else: self.year_c = datetime.datetime.today().year self.fecha_m = datetime.datetime.today() super(OtorgadosAlumnos, self).save(*args, **kwargs)

5.4 B.3 Modelos de datos de la aplicación divulgación. #! /usr/bin/python # -*- coding: utf-8 -*- #------------------------------- # models.py de la app divulgacion #---------------------------------------- from django.db import models from django.contrib.auth.models import User from siaa.generales.models import TipoProducto, TipoEvento, MediosDifusion, Pais, Region, TipoParticipacion,

CategoriaDivulga, Ambito, Publico import datetime

YEAR = datetime.datetime.now().year T_PARTICIPACION=( (1,'Plática'), (2,'Póster'), (5,'Talleres'), (6,'Otra actividad'), ) class ProduccionEditorial(models.Model): nombre_publicacion = models.CharField('Nombre de la publicación', max_length=200) tipo_producto = models.ForeignKey(TipoProducto, verbose_name='Tipo de producto') tiraje = models.IntegerField('Tiraje') circulacion_impresa = models.BooleanField('Impreso') circulacion_electronica = models.BooleanField('Electrónico') firma = models.BooleanField(default=False) #prescindible #Campos de control ---> propietario = models.ForeignKey(User, verbose_name='Académico', null=True, blank=True, related_name='P_Dv_PE') fecha_c = models.DateField(editable=False, null=True, blank=True) fecha_m = models.DateField(null=True, blank=True) year_c = models.IntegerField('Año de reporte', editable=False, null=True, blank=True) def save(self, *args, **kwargs): ''' On save, update timestamps ''' if not self.id: self.fecha_c = datetime.datetime.today() if datetime.datetime.today().month == 01: self.year_c = datetime.datetime.today().year-1 else: self.year_c = datetime.datetime.today().year self.fecha_m = datetime.datetime.today() super(ProduccionEditorial, self).save(*args, **kwargs)

class Meta: ordering= ['propietario','nombre_publicacion'] verbose_name='Producción editorial' verbose_name_plural='Producciones editoriales' def __unicode__(self): return self.nombre_publicacion

class Articulos(models.Model): tipo_doc = models.ForeignKey(CategoriaDivulga, verbose_name="Tipo de publicación", related_name='P_Dv_Art') titulo = models.CharField('Título', max_length=300) nom_publica = models.CharField('Nombre de la publicación', max_length=200, help_text='Revista, periodico,

etc.') electronic_only = models.BooleanField('Solo electrónico') fecha_pub = models.DateField('Fecha de publicacion', null=True, blank=True) year = models.IntegerField('Año', default=YEAR) volumen = models.IntegerField(null=True, blank=True) numero = models.IntegerField(null=True, blank=True) pagina_ini = models.IntegerField('de la', null=True, blank=True)

Page 36: Desarrollo e implementación del Sistema de Información ...

3

6

pagina_fin = models.IntegerField('a la', null=True, blank=True) isbn = models.CharField('ISBN/ISSN', max_length=50, null=True, blank=True) autores = models.TextField('Lista completa de autores', null=True, blank=True) #Campos de control ---> propietario = models.ForeignKey(User, null=True, blank=True, verbose_name="Académico", related_name='Dv_Ar_p') fecha_c = models.DateField(editable=False, null=True, blank=True) fecha_m = models.DateField(null=True, blank=True) year_c = models.IntegerField('Año de reporte', editable=False, null=True, blank=True) class Meta: ordering= ['propietario','titulo'] verbose_name='Artículo de divulgación' verbose_name_plural='Artículos de divulgación' def __unicode__(self): return self.titulo def save(self, *args, **kwargs): ''' On save, update timestamps''' if not self.id: self.fecha_c = datetime.datetime.today() if datetime.datetime.today().month == 01: self.year_c = datetime.datetime.today().year-1 else: self.year_c = datetime.datetime.today().year self.fecha_m = datetime.datetime.today() super(Articulos, self).save(*args, **kwargs) class Eventos_Organizacion(models.Model): nombre_evento = models.CharField('Nombre del evento', max_length=300) tipo_evento = models.ForeignKey(TipoEvento, verbose_name='Tipo de evento', related_name='TE_Dv_O') fecha_inicio = models.DateField('Fecha de inicio') fecha_termino = models.DateField('Fecha de término') lugar_pais = models.ForeignKey(Pais, verbose_name="País", related_name='Pais_Dv_O', default=159) lugar_ciudad = models.CharField('Ciudad y Estado', max_length=100, help_text='Ciudad y estado(provincia o

región)') n_ponentes = models.IntegerField('Número de ponentes', default=0) n_asistentes = models.IntegerField('Número de asistentes', default=0) publico = models.ForeignKey(Publico, verbose_name='Público al que estuvo dirigido', default=7) #Campos de control ---> propietario = models.ForeignKey(User, verbose_name='Académico', null=True, blank=True, related_name='P_Dv_Org') fecha_c = models.DateField(editable=False, null=True, blank=True) fecha_m = models.DateField(null=True, blank=True) year_c = models.IntegerField('Año de reporte', editable=False, null=True, blank=True) def save(self, *args, **kwargs): ''' On save, update timestamps ''' if not self.id: self.fecha_c = datetime.datetime.today() if datetime.datetime.today().month == 01: self.year_c = datetime.datetime.today().year-1 else: self.year_c = datetime.datetime.today().year self.fecha_m = datetime.datetime.today() super(Eventos_Organizacion, self).save(*args, **kwargs) class Meta: ordering=['propietario','nombre_evento',] verbose_name='Evento' verbose_name_plural='Eventos Organizados'

def __unicode__(self): return self.nombre_evento

class Eventos_Presentacion(models.Model): nombre_evento = models.CharField('Evento', max_length=300, help_text='Nombre del evento donde tuvo lugar la

presentación') tipo_evento = models.ForeignKey(TipoEvento, verbose_name='Tipo de evento') titulo_presentacion = models.CharField('Título de la presentación', max_length=200) fecha = models.DateField('Fecha del evento', null=True, blank=True) lugar_pais = models.ForeignKey(Pais, verbose_name="País", default=159) lugar_ciudad = models.CharField('Ciudad y Estado', max_length=100, help_text='Ciudad y estado donde se llevo a

cabo el evento') invitacion = models.BooleanField('Por invitación directa') tipo_particip = models.IntegerField('Tipo de participación', choices=T_PARTICIPACION)

Page 37: Desarrollo e implementación del Sistema de Información ...

3

7

organiza_crya = models.BooleanField('Organizado por el CRyA') publico = models.ForeignKey(Publico, verbose_name='Público al que estuvo dirigido', default=7) #Campos de control ---> propietario = models.ForeignKey(User, verbose_name='Académico', null=True, blank=True, related_name='P_Dv_EP') fecha_c = models.DateField(editable=False, null=True, blank=True) fecha_m = models.DateField(null=True, blank=True) year_c = models.IntegerField('Año de reporte', editable=False, null=True, blank=True) def save(self, *args, **kwargs): ''' On save, update timestamps ''' if not self.id: self.fecha_c = datetime.datetime.today() if datetime.datetime.today().month == 01: self.year_c = datetime.datetime.today().year-1 else: self.year_c = datetime.datetime.today().year self.fecha_m = datetime.datetime.today() super(Eventos_Presentacion, self).save(*args, **kwargs) class Meta: ordering=['propietario','tipo_evento','nombre_evento',] verbose_name='Presentación' verbose_name_plural='Presentaciones en eventos'

def __unicode__(self): return self.titulo_presentacion

class ProduccionProgramas(models.Model): nombre_programa = models.CharField('Nombre del programa', max_length=100) tema = models.CharField('Tema del programa', max_length=100) medio = models.ForeignKey(MediosDifusion, verbose_name='Medio de difusión') estacion = models.CharField('Estación en la que se difunde', max_length=100, help_text='Nombre, Frecuencia,

Canal o Página Web') fecha =models.DateField('Fecha del programa', null=True, blank=True) entrevistado = models.CharField('Personaje entrevistado', max_length=50, null=True, blank=True) tema_entrevista = models.CharField('Tema de la entrevista', max_length=100, null=True, blank=True) #Campos de control ---> propietario = models.ForeignKey(User, verbose_name='Académico', null=True, blank=True, related_name='P_Dv_PP') fecha_c = models.DateField(editable=False, null=True, blank=True) fecha_m = models.DateField(null=True, blank=True) year_c = models.IntegerField('Año de reporte', editable=False, null=True, blank=True) def save(self, *args, **kwargs): ''' On save, update timestamps ''' if not self.id: self.fecha_c = datetime.datetime.today() if datetime.datetime.today().month == 01: self.year_c = datetime.datetime.today().year-1 else: self.year_c = datetime.datetime.today().year self.fecha_m = datetime.datetime.today() super(ProduccionProgramas, self).save(*args, **kwargs) class Meta: ordering=['propietario','nombre_programa'] verbose_name='Producción de programa' verbose_name_plural='Producción de programas (Radio, TV e Internet)' def __unicode__(self): return self.nombre_programa

class Entrevistas(models.Model): nombre_programa = models.CharField('Nombre del programa', max_length=100) medio = models.ForeignKey(MediosDifusion, verbose_name='Medio de difusión') estacion = models.CharField('Nombre de medio', max_length=100, help_text='Nombre del medio donde se difunde,

frecuencia, canal, medio impreso ó página Web, ') fecha =models.DateField('Fecha de la entrevista', null=True, blank=True) tema_entrevista = models.CharField('Tema de la entrevista', max_length=100) #Campos de control ---> propietario = models.ForeignKey(User, verbose_name='Académico', null=True, blank=True, related_name='P_Dv_En') fecha_c = models.DateField(editable=False, null=True, blank=True) fecha_m = models.DateField(null=True, blank=True) year_c = models.IntegerField('Año de reporte', editable=False, null=True, blank=True)

Page 38: Desarrollo e implementación del Sistema de Información ...

3

8

def save(self, *args, **kwargs): ''' On save, update timestamps ''' if not self.id: self.fecha_c = datetime.datetime.today() if datetime.datetime.today().month == 01: self.year_c = datetime.datetime.today().year-1 else: self.year_c = datetime.datetime.today().year self.fecha_m = datetime.datetime.today() super(Entrevistas, self).save(*args, **kwargs) class Meta: ordering=['propietario','nombre_programa'] verbose_name='Entrevista' verbose_name_plural='Entrevistas' def __unicode__(self): return self.tema_entrevista

5.5 B.4 Modelos de datos de la aplicación docencia. #! /usr/bin/python # -*- coding: utf-8 -*- #---------------------------------- # models.py de la app docencia #----------------------------------- from django.db import models from django.db.models import Q from django.contrib.auth.models import User from siaa.generales.models import ClasificacionCONACyT, Pais, TiposBeca, Escolaridad, TemasExamen from siaa.academicos.models import Academicos import datetime YEAR = datetime.date.today().year SEXO=( ('M','Masculino'), ('F','Femenino'), ) TIPO=( (1,'Básicos'), (2,'Optativos'), (3,'Propedeúticos'), ) MODALIDAD = ( (1,'Tesis'), (2,'Artículo'), (3,'Protocolo'), (4,'Exámen GC'), ) TESIS_STATUS = ( (1,'En proceso'), (2,'Terminada'), ) class ProgramasCRyA(models.Model): programa= models.CharField('Programa / Carrera', max_length=150) activa = models.BooleanField('Programa activo') class Meta: verbose_name = 'Programa CRyA' verbose_name_plural = 'Programas CRyA' ordering= ['id'] def __unicode__(self): return self.programa #Llenados por la persona encargada de posgrado class CursosRegulares(models.Model): nivel= models.IntegerField('Tipo', choices=TIPO, help_text="Tipo de curso") clas_conacyt= models.ForeignKey(ClasificacionCONACyT, verbose_name='Clasificación CONACyT', help_text='En caso

de ser posgrado clasificado por CONACyT', null=True, blank=True)

Page 39: Desarrollo e implementación del Sistema de Información ...

3

9

programa = models.ForeignKey(ProgramasCRyA, limit_choices_to=Q(activa=1)) curso = models.CharField('Curso/Materia', max_length=200) fecha_ini = models.DateField('Fecha de inicio', null=True, blank=True) fecha_fin = models.DateField('Fecha de fin', null=True, blank=True) num_c = models.IntegerField('Número de grupos', default=0, help_text="Número de veces que se impartió el curso

en el año") horas = models.IntegerField('Total de horas impartidas', default=0) activa = models.BooleanField('Materia impartiendose') class Meta: ordering= ['nivel','curso'] verbose_name='Curso regular (Posgrado UNAM)' verbose_name_plural='Lista de cursos regulares (Posgrado UNAM)' def __unicode__(self): return self.curso

class CursosDocentes(models.Model): curso = models.ForeignKey(CursosRegulares, verbose_name='Curso', limit_choices_to=Q(activa=1)) horas = models.IntegerField('Horas impartidas', default=0) coolaboracion =models.BooleanField('En Colaboración') #Campos de control propietario = models.ForeignKey(User, verbose_name='Académico', null=True, blank=True) fecha_c = models.DateField(editable=False, null=True, blank=True) fecha_m = models.DateField(null=True, blank=True) year_c = models.IntegerField('Año de reporte', editable=False, null=True, blank=True)

def save(self, *args, **kwargs): ''' On save, update timestamps ''' if not self.id: self.fecha_c = datetime.datetime.today() if datetime.datetime.today().month == 01: self.year_c = datetime.datetime.today().year-1 else: self.year_c = datetime.datetime.today().year self.fecha_m = datetime.datetime.today() super(CursosDocentes , self).save(*args, **kwargs) class Meta: ordering= ['propietario', 'curso'] verbose_name='Curso regular (Posgrado UNAM)' verbose_name_plural='Cursos regulares (Posgrado UNAM)' def __unicode__(self): return self.curso.curso class CursosRegularesLic(models.Model): nivel= models.ForeignKey(Escolaridad, verbose_name='Nivel', limit_choices_to=Q(id=2), default=2) institucion = models.CharField('Institución', max_length=100) curso = models.CharField('Curso/Materia', max_length=200) num_c = models.IntegerField('Número de grupos', default=0, help_text="Número de veces que se impartió el curso

en el año") horas = models.IntegerField('Total de horas impartidas', default=0) coolaboracion =models.BooleanField('En Colaboración') #Campos de control propietario = models.ForeignKey(User, verbose_name='Académico', null=True, blank=True) fecha_c = models.DateField(editable=False, null=True, blank=True) fecha_m = models.DateField(null=True, blank=True) year_c = models.IntegerField('Año de reporte', editable=False, null=True, blank=True) def save(self, *args, **kwargs): ''' On save, update timestamps ''' if not self.id: self.fecha_c = datetime.datetime.today() if datetime.datetime.today().month == 01: self.year_c = datetime.datetime.today().year-1 else: self.year_c = datetime.datetime.today().year self.fecha_m = datetime.datetime.today() super(CursosRegularesLic, self).save(*args, **kwargs) class Meta: ordering= ['propietario', 'curso'] verbose_name='Curso regular (Licenciatura UNAM)'

Page 40: Desarrollo e implementación del Sistema de Información ...

4

0

verbose_name_plural='Cursos regulares (Licenciatura UNAM)' def __unicode__(self): return self.curso class CursosExtLic(models.Model): nivel= models.ForeignKey(Escolaridad, verbose_name='Nivel', limit_choices_to=Q(id=2), default=2) pais = models.ForeignKey(Pais, verbose_name="Pais", related_name='FK_Dc_CEL_p', default=159) institucion = models.CharField('Institución', max_length=100) curso = models.CharField('Curso/Materia', max_length=200) num_c = models.IntegerField('Número de grupos', default=0, help_text="Número de veces que se impartió el curso

en el año") horas = models.IntegerField('Total de horas impartidas', default=0) coolaboracion =models.BooleanField('En Colaboración') #Campos de control propietario = models.ForeignKey(User, verbose_name='Académico', null=True, blank=True) fecha_c = models.DateField(editable=False, null=True, blank=True) fecha_m = models.DateField(null=True, blank=True) year_c = models.IntegerField('Año de reporte', editable=False, null=True, blank=True) def save(self, *args, **kwargs): ''' On save, update timestamps ''' if not self.id: self.fecha_c = datetime.datetime.today() if datetime.datetime.today().month == 01: self.year_c = datetime.datetime.today().year-1 else: self.year_c = datetime.datetime.today().year self.fecha_m = datetime.datetime.today() super(CursosExtLic, self).save(*args, **kwargs) class Meta: ordering= ['propietario', 'curso'] verbose_name='Curso externo (Licenciatura)' verbose_name_plural='Cursos externos (Licenciatura)' def __unicode__(self): return self.curso class CursosExtPos(models.Model): nivel= models.ForeignKey(Escolaridad, verbose_name='Nivel', limit_choices_to=Q(id=5) | Q(id=7)) pais = models.ForeignKey(Pais, verbose_name="Pais", related_name='FK_Dc_CEP_p', default=159) institucion = models.CharField('Institución', max_length=100) curso = models.CharField('Curso/Materia', max_length=200) num_c = models.IntegerField('Número de grupos', default=0, help_text="Número de veces que se impartió el curso

en el año") horas = models.IntegerField('Total de horas impartidas', default=0) coolaboracion =models.BooleanField('En Colaboración') #Campos de control propietario = models.ForeignKey(User, verbose_name='Académico', null=True, blank=True) fecha_c = models.DateField(editable=False, null=True, blank=True) fecha_m = models.DateField(null=True, blank=True) year_c = models.IntegerField('Año de reporte', editable=False, null=True, blank=True) def save(self, *args, **kwargs): ''' On save, update timestamps ''' if not self.id: self.fecha_c = datetime.datetime.today() if datetime.datetime.today().month == 01: self.year_c = datetime.datetime.today().year-1 else: self.year_c = datetime.datetime.today().year self.fecha_m = datetime.datetime.today() super(CursosExtPos, self).save(*args, **kwargs) class Meta: ordering= ['propietario', 'curso'] verbose_name='Curso externo (Posgrado)' verbose_name_plural='Cursos externos (Posgrado)' def __unicode__(self): return self.curso class CursosUnicos(models.Model): curso = models.CharField('Curso/Materia', max_length=200) pais = models.ForeignKey(Pais, verbose_name='Pais', related_name='FK_Dc_CE_p', default=159) institucion = models.CharField('Institución', max_length=200)

Page 41: Desarrollo e implementación del Sistema de Información ...

4

1

horas = models.IntegerField('Horas impartidas', default=0) #Campos de control propietario = models.ForeignKey(User, verbose_name='Académico', null=True, blank=True) fecha_c = models.DateField(editable=False, null=True, blank=True) fecha_m = models.DateField(null=True, blank=True) year_c = models.IntegerField('Año de reporte', editable=False, null=True, blank=True) def save(self, *args, **kwargs): ''' On save, update timestamps ''' if not self.id: self.fecha_c = datetime.datetime.today() if datetime.datetime.today().month == 01: self.year_c = datetime.datetime.today().year-1 else: self.year_c = datetime.datetime.today().year self.fecha_m = datetime.datetime.today() super(CursosUnicos, self).save(*args, **kwargs) class Meta: ordering= ['propietario', 'curso'] verbose_name='Curso único' verbose_name_plural='Cursos únicos' def __unicode__(self): return self.curso class Tutorias(models.Model): alumno = models.CharField('Alumno', max_length=150) genero = models.CharField('Género', max_length=1, choices=SEXO, null=True, blank=True) fecha_nac = models.DateField('Fecha de Nacimiento', null=True, blank=True) #nacionalidad pais_nac = models.ForeignKey(Pais, verbose_name='Pais', related_name='FK_Dc_T_pn', null=True, blank=True,

default=159) estado_nac = models.CharField('Estado', max_length=60, null=True, blank=True) #Procedencia pais_inst = models.ForeignKey(Pais, verbose_name='Pais', related_name='FK_Dc_T_pi', null=True, blank=True,

default=159) institucion = models.CharField('Institución', max_length=200, null=True, blank=True) nivel_proc= models.ForeignKey(Escolaridad, verbose_name='Nivel', limit_choices_to=Q(id=2) | Q(id=5)|

Q(id=7)|Q(id=3), related_name='D', null=True, blank=True, help_text="Nivel que cursa en la institución de procedencia") programa = models.CharField('Programa', max_length=200, null=True, blank=True) #------- #En la entidad cursa nivel= models.ForeignKey(Escolaridad, verbose_name='Nivel', limit_choices_to=Q(id=2) | Q(id=5)|

Q(id=7)|Q(id=4), null=True, blank=True) serv_social = models.BooleanField('Servicio social', default=False) fecha_ini = models.DateField('Fecha de ingreso', null=True, blank=True) fecha_fin = models.DateField('Fecha de egreso', null=True, blank=True) #proyecto en el que participo en caso de proyecto = models.CharField('Proyecto', max_length=200, null=True, blank=True) #En caso de ser graduado edad_grad = models.IntegerField('Edad de graduación', default=0, null=True, blank=True) fecha_grad = models.DateField('Fecha de graduación', null=True, blank=True) beca = models.ForeignKey(TiposBeca, verbose_name='cuenta con beca', null=True, blank=True) tesis = models.CharField('Título de la tesis', max_length=300, null=True, blank=True, default="Sin título") tesis_status = models.IntegerField('Estatus', choices=TESIS_STATUS, null=True, blank=True) tesis_asesor = models.ForeignKey(Academicos, verbose_name='Asesor', limit_choices_to=Q(tipo_academico=1),

null=True, blank=True, related_name="asesor1") tesis_asesor2 = models.ForeignKey(Academicos, verbose_name='Asesor', limit_choices_to=Q(tipo_academico=1),

null=True, blank=True, help_text='Llenar este campo en caso de que el alumno tenga un segundo asesor de tesis',

related_name="asesor2") #Graduacion graduado = models.BooleanField('Graduado', help_text='Marcar si el alumno se graduó en el año') graduado_fecha = models.DateField('Fecha', help_text='Fecha de graduación en el CRyA', null=True, blank=True) graduado_modalidad = models.IntegerField('Modalidad', choices=MODALIDAD, null=True, blank=True) graduado_work = models.CharField('Título del trabajo escrito', max_length=200,

help_text='(tesis/artículo/protocolo)', default="Título por definir") #Campos de control propietario = models.ForeignKey(User, verbose_name='Propietario', null=True, blank=True,

related_name="FK_D_T_p") fecha_c = models.DateField(editable=False, null=True, blank=True) fecha_m = models.DateField(null=True, blank=True) year_c = models.IntegerField('Año de reporte', editable=False, null=True, blank=True)

Page 42: Desarrollo e implementación del Sistema de Información ...

4

2

class Meta: ordering= ['nivel','alumno'] verbose_name='Alumno' verbose_name_plural='Alumnos' def __unicode__(self): return self.alumno def save(self, *args, **kwargs): ''' On save, update timestamps ''' if not self.id: self.fecha_c = datetime.datetime.today() if datetime.datetime.today().month == 01: self.year_c = datetime.datetime.today().year-1 else: self.year_c = datetime.datetime.today().year self.fecha_m = datetime.datetime.today() super(Tutorias, self).save(*args, **kwargs)

class TrabajosEscritos(Tutorias): class Meta: proxy = True verbose_name = 'Trabajo Escrito (asesoria)' verbose_name_plural = 'Dirección de trabajos escritos (Posgrado UNAM)' class ComiteTutoral(models.Model): academico = models.ForeignKey(Academicos, verbose_name='Académico') tutorado = models.ForeignKey(Tutorias, limit_choices_to =(Q(fecha_c__year=YEAR) & ~Q(fecha_c__month=01))) tutor_principal= models.BooleanField('Tutor principal') #Campos de control propietario = models.ForeignKey(User, verbose_name='Tutor', null=True, blank=True, related_name="FK_D_CT_p") fecha_c = models.DateField(editable=False, null=True, blank=True) fecha_m = models.DateField(null=True, blank=True) year_c = models.IntegerField('Año de reporte', editable=False, null=True, blank=True) class Meta: ordering= ['propietario','tutorado'] verbose_name='Tutoria' verbose_name_plural='Comites tutorales' def __unicode__(self): return self.tutorado.alumno def save(self, *args, **kwargs): ''' On save, update timestamps ''' if not self.id: self.fecha_c = datetime.datetime.today() if datetime.datetime.today().month == 01: self.year_c = datetime.datetime.today().year-1 else: self.year_c = datetime.datetime.today().year self.fecha_m = datetime.datetime.today() super(ComiteTutoral, self).save(*args, **kwargs)

class AsesoriasExternas(models.Model): alumno = models.CharField('Alumno', max_length=150) #nacionalidad pais_nac = models.ForeignKey(Pais, verbose_name='Pais', related_name='FK_Dc_AE_pn', default=159) estado_nac = models.CharField('Estado', max_length=60, null=True, blank=True) #institucion pais_inst = models.ForeignKey(Pais, verbose_name='Pais', related_name='FK_Dc_AE_pi', default=159) institucion = models.CharField('Institucion', max_length=200) nivel= models.ForeignKey(Escolaridad, verbose_name='Nivel', limit_choices_to=Q(id=5) | Q(id=2)|

Q(id=1)|Q(id=7)) fecha_ini = models.DateField('Inicio de asesoria', null=True, blank=True) fecha_fin = models.DateField('Termino de asesoria', null=True, blank=True) proyecto_tesis = models.CharField('Título de la tesis o proyecto', max_length=300) fecha_grad = models.DateField('Fecha de graduación', null=True, blank=True) graduado = models.BooleanField('Graduado') #Campos de control propietario = models.ForeignKey(User, verbose_name='Asesor', null=True, blank=True) fecha_c = models.DateField(null=True, blank=True)

Page 43: Desarrollo e implementación del Sistema de Información ...

4

3

fecha_m = models.DateField(null=True, blank=True) year_c = models.IntegerField('Año de reporte', editable=False, null=True, blank=True) def save(self, *args, **kwargs): ''' On save, update timestamps ''' if not self.id: self.fecha_c = datetime.datetime.today() if datetime.datetime.today().month == 01: self.year_c = datetime.datetime.today().year-1 else: self.year_c = datetime.datetime.today().year self.fecha_m = datetime.datetime.today() super(AsesoriasExternas, self).save(*args, **kwargs)

class Meta: ordering= ['propietario','alumno'] verbose_name='Direccion de tesis externa' verbose_name_plural='Dirección de tesis (estudiantes externos)' def __unicode__(self): return self.alumno class SinodalExTematico(models.Model): fecha = models.DateField('Fecha de examen') tema_exa = models.ForeignKey(TemasExamen, verbose_name='Tema de examen') es_cordinador = models.BooleanField('Coordinador', help_text='Seleccionar si tuvo participación como

coordinador') #Campos de control propietario = models.ForeignKey(User, verbose_name='Sinodal', null=True, blank=True) fecha_c = models.DateField(null=True, blank=True) fecha_m = models.DateField(null=True, blank=True) year_c = models.IntegerField('Año de reporte', editable=False, null=True, blank=True) def save(self, *args, **kwargs): ''' On save, update timestamps ''' if not self.id: self.fecha_c = datetime.datetime.today() if datetime.datetime.today().month == 01: self.year_c = datetime.datetime.today().year-1 else: self.year_c = datetime.datetime.today().year self.fecha_m = datetime.datetime.today() super(SinodalExTematico, self).save(*args, **kwargs)

class Meta: ordering= ['propietario','tema_exa'] verbose_name='Sinodal (Examen temático)' verbose_name_plural='Sinodales (Exámenes temáticos)' def __unicode__(self): return self.tema_exa.tema

class SinodalExGeneral(models.Model): fecha = models.DateField('Fecha de examen') es_cordinador = models.BooleanField('Coordinador', help_text='Seleccionar si tuvo participación como

coordinador') #Campos de control propietario = models.ForeignKey(User, verbose_name='Sinodal', null=True, blank=True,

related_name='FK_D_SEGC_p') fecha_c = models.DateField(null=True, blank=True) fecha_m = models.DateField(null=True, blank=True) year_c = models.IntegerField('Año de reporte', editable=False, null=True, blank=True) def save(self, *args, **kwargs): ''' On save, update timestamps ''' if not self.id: self.fecha_c = datetime.datetime.today() if datetime.datetime.today().month == 01: self.year_c = datetime.datetime.today().year-1 else: self.year_c = datetime.datetime.today().year self.fecha_m = datetime.datetime.today() super(SinodalExGeneral, self).save(*args, **kwargs)

Page 44: Desarrollo e implementación del Sistema de Información ...

4

4

class Meta: ordering= ['propietario','fecha'] verbose_name='Sinodal (Examen general de conocimientos)' verbose_name_plural='Sinodal (Exámenes generales de conocimientos)' def __unicode__(self): return u'%s, %s' % (self.propietario.last_name, self.propietario.first_name)

class SinodalExCandidatura(models.Model): alumno = models.CharField('Alumno', max_length=150) fecha = models.DateField('Fecha de examen') institucion = models.CharField('Institución', max_length=100) #Campos de control propietario = models.ForeignKey(User, verbose_name='Sinodal', null=True, blank=True) fecha_c = models.DateField(null=True, blank=True) fecha_m = models.DateField(null=True, blank=True) year_c = models.IntegerField('Año de reporte', editable=False, null=True, blank=True) def save(self, *args, **kwargs): ''' On save, update timestamps ''' if not self.id: self.fecha_c = datetime.datetime.today() if datetime.datetime.today().month == 01: self.year_c = datetime.datetime.today().year-1 else: self.year_c = datetime.datetime.today().year self.fecha_m = datetime.datetime.today() super(SinodalExCandidatura, self).save(*args, **kwargs)

class Meta: ordering= ['propietario','alumno'] verbose_name='Sinodal (Examen de candidatura)' verbose_name_plural='Sinodal (Exámenes de candidatura)' def __unicode__(self): return self.alumno

class SinodalExGrado(models.Model): alumno = models.CharField('Alumno', max_length=150) fecha = models.DateField('Fecha de examen') nivel = models.ForeignKey(Escolaridad, verbose_name="Nivel", null=True, blank=True, limit_choices_to=Q(id=2) |

Q(id=5)|Q(id=7)) institucion = models.CharField('Institución', max_length=100) #Campos de control propietario = models.ForeignKey(User, verbose_name='Sinodal', null=True, blank=True) fecha_c = models.DateField(null=True, blank=True) fecha_m = models.DateField(null=True, blank=True) year_c = models.IntegerField('Año de reporte', editable=False, null=True, blank=True) def save(self, *args, **kwargs): ''' On save, update timestamps ''' if not self.id: self.fecha_c = datetime.datetime.today() if datetime.datetime.today().month == 01: self.year_c = datetime.datetime.today().year-1 else: self.year_c = datetime.datetime.today().year self.fecha_m = datetime.datetime.today() super(SinodalExGrado, self).save(*args, **kwargs)

class Meta: ordering= ['propietario','alumno'] verbose_name='Sinodal (Examen de grado)' verbose_name_plural='Sinodal (Exámenes de grado)' def __unicode__(self): return self.alumno

Page 45: Desarrollo e implementación del Sistema de Información ...

4

5

5.6 B.5 Modelos de datos de la aplicación intercambio. #! /usr/bin/python # -*- coding: utf-8 -*- #------------------------------------ # Modelos de la app Intercambio #------------------------------------ from django.db import models from django.contrib.auth.models import User from siaa.generales.models import Departamentos, Pais, Region import datetime class VisitasInt(models.Model): nombre = models.CharField('Nombre del visitante', max_length=100) departamento = models.ForeignKey(Departamentos, verbose_name='Línea de investigación') pais_institucion = models.ForeignKey(Pais, verbose_name='Pais', default=159) institucion = models.CharField('Institución', max_length=100) actividad = models.TextField('Actividad(es) que realiza') fecha_inicio = models.DateField('Fecha de llegada') fecha_fin = models.DateField('Fecha de regreso') intercambio_unam = models.BooleanField('Programa de intercambio UNAM') financiamiento = models.CharField('Otro financiamiento', max_length=100, null=True, blank=True, ) #Campos de control ---> propietario = models.ForeignKey(User, null=True, blank=True, related_name='I_VI_p') fecha_c = models.DateField(editable=False, null=True, blank=True) fecha_m = models.DateField(null=True, blank=True) year_c = models.IntegerField('Año de reporte', editable=False, null=True, blank=True) class Meta: ordering= ['nombre'] verbose_name='Visitante Internacional' verbose_name_plural='Visitantes Internacionales' def __unicode__(self): return self.nombre def save(self, *args, **kwargs): ''' On save, update timestamps''' if not self.id: self.fecha_c = datetime.datetime.today() if datetime.datetime.today().month == 01: self.year_c = datetime.datetime.today().year-1 else: self.year_c = datetime.datetime.today().year self.fecha_m = datetime.datetime.today() super(VisitasInt, self).save(*args, **kwargs) class VisitasNac(models.Model): nombre = models.CharField('Nombre del visitante', max_length=100) departamento = models.ForeignKey(Departamentos, verbose_name='Línea de investigación') estado = models.ForeignKey(Region, verbose_name='Estado') institucion = models.CharField('Institución', max_length=100) actividad = models.TextField('Actividad(es) que realiza') fecha_inicio = models.DateField('Fecha de llegada') fecha_fin = models.DateField('Fecha de regreso') intercambio_unam = models.BooleanField('Programa de intercambio UNAM') financiamiento = models.CharField('Otro financiamiento', max_length=100, null=True, blank=True) #Campos de control ---> propietario = models.ForeignKey(User, null=True, blank=True, related_name='I_VN_p') fecha_c = models.DateField(editable=False, null=True, blank=True) fecha_m = models.DateField(null=True, blank=True) year_c = models.IntegerField('Año de reporte', editable=False, null=True, blank=True) class Meta: ordering= ['nombre'] verbose_name='Visitante Nacional' verbose_name_plural='Visitantes Nacionales' def __unicode__(self): return self.nombre def save(self, *args, **kwargs): ''' On save, update timestamps''' if not self.id: self.fecha_c = datetime.datetime.today()

Page 46: Desarrollo e implementación del Sistema de Información ...

4

6

if datetime.datetime.today().month == 01: self.year_c = datetime.datetime.today().year-1 else: self.year_c = datetime.datetime.today().year self.fecha_m = datetime.datetime.today() super(VisitasNac, self).save(*args, **kwargs) class SalidasInt(models.Model): departamento = models.ForeignKey(Departamentos, verbose_name='Línea de investigación') pais_institucion = models.ForeignKey(Pais, verbose_name='Pais', default=159) institucion = models.CharField('Institución', max_length=100) actividad = models.TextField('Actividad(es) que realiza') fecha_inicio = models.DateField('Fecha de inicio') fecha_fin = models.DateField('Fecha de término') intercambio_unam = models.BooleanField('Programa de intercambio UNAM') financiamiento = models.CharField('Otro financiamiento', max_length=100, null=True, blank=True) #Campos de control ---> propietario = models.ForeignKey(User, related_name='ISI_p') fecha_c = models.DateField(editable=False, null=True, blank=True) fecha_m = models.DateField(null=True, blank=True) year_c = models.IntegerField('Año de reporte', editable=False, null=True, blank=True) class Meta: ordering= ['propietario'] verbose_name='Estancia de trabajo en el extranjero' verbose_name_plural='Estancias de trabajo en el extranjero' def __unicode__(self): return u'%s, %s' % (self.propietario.last_name, self.propietario.first_name) def save(self, *args, **kwargs): ''' On save, update timestamps''' if not self.id: self.fecha_c = datetime.datetime.today() if datetime.datetime.today().month == 01: self.year_c = datetime.datetime.today().year-1 else: self.year_c = datetime.datetime.today().year self.fecha_m = datetime.datetime.today() super(SalidasInt, self).save(*args, **kwargs) class SalidasNac(models.Model): departamento = models.ForeignKey(Departamentos, verbose_name='Línea de investigación') estado_institucion = models.ForeignKey(Region, verbose_name='Estado') institucion = models.CharField('Institución', max_length=100) actividad = models.TextField('Actividad(es) que realiza') fecha_inicio = models.DateField('Fecha de inicio') fecha_fin = models.DateField('Fecha de término') intercambio_unam = models.BooleanField('Programa de intercambio UNAM') financiamiento = models.CharField('Otro financiamiento', max_length=100, null=True, blank=True) #Campos de control ---> propietario = models.ForeignKey(User, null=True, blank=True, related_name='I_SN_p') fecha_c = models.DateField(editable=False, null=True, blank=True) fecha_m = models.DateField(null=True, blank=True) year_c = models.IntegerField('Año de reporte', editable=False, null=True, blank=True) class Meta: ordering= ['propietario'] verbose_name='Estancia de trabajo nacional' verbose_name_plural='Estancias de trabajo nacionales' def __unicode__(self): return u'%s, %s' % (self.propietario.last_name, self.propietario.first_name) def save(self, *args, **kwargs): ''' On save, update timestamps''' if not self.id: self.fecha_c = datetime.datetime.today() if datetime.datetime.today().month == 01: self.year_c = datetime.datetime.today().year-1 else: self.year_c = datetime.datetime.today().year self.fecha_m = datetime.datetime.today() super(SalidasNac, self).save(*args, **kwargs)

Page 47: Desarrollo e implementación del Sistema de Información ...

4

7

class SabaticosAcademicos(models.Model): pais_institucion = models.ForeignKey(Pais, verbose_name='Pais', default=159) institucion = models.CharField('Institución', max_length=100) actividad = models.TextField('Actividad(es) que realiza') fecha_inicio = models.DateField('Fecha de inicio') fecha_fin = models.DateField('Fecha de término') financia_unam = models.BooleanField('Beca DGAPA') beca_conacyt = models.BooleanField('Beca CONACyT') financia_entidad = models.BooleanField('Propio del CRyA') financia_otra = models.BooleanField('Financiamiento de la institución extranjera') #Campos de control ---> propietario = models.ForeignKey(User, null=True, blank=True, related_name='I_SI_p', verbose_name="Académico") fecha_c = models.DateField(editable=False, null=True, blank=True) fecha_m = models.DateField(null=True, blank=True) year_c = models.IntegerField('Año de reporte', editable=False, null=True, blank=True) class Meta: ordering= ['propietario'] verbose_name='Estancia sabática' verbose_name_plural='Estancias Sabáticas' def __unicode__(self): return u'%s, %s' % (self.propietario.last_name, self.propietario.first_name) def save(self, *args, **kwargs): ''' On save, update timestamps''' if not self.id: self.fecha_c = datetime.datetime.today() if datetime.datetime.today().month == 01: self.year_c = datetime.datetime.today().year-1 else: self.year_c = datetime.datetime.today().year self.fecha_m = datetime.datetime.today() super(SabaticosAcademicos, self).save(*args, **kwargs) class SabaticosEntidad(models.Model): nombre = models.CharField('Nombre del visitante', max_length=100) pais_institucion = models.ForeignKey(Pais, verbose_name='Pais', default=159) institucion = models.CharField('Institución', max_length=100) actividad = models.TextField('Actividad(es) que realiza') fecha_inicio = models.DateField('Fecha de inicio') fecha_fin = models.DateField('Fecha de término') #Campos de control ---> fecha_c = models.DateField(editable=False, null=True, blank=True) fecha_m = models.DateField(null=True, blank=True) year_c = models.IntegerField('Año de reporte', editable=False, null=True, blank=True) class Meta: ordering= ['nombre'] verbose_name='Sabático en la Entidad' verbose_name_plural='Sabáticos en la Entidad' def __unicode__(self): return self.nombre def save(self, *args, **kwargs): ''' On save, update timestamps''' if not self.id: self.fecha_c = datetime.datetime.today() if datetime.datetime.today().month == 01: self.year_c = datetime.datetime.today().year-1 else: self.year_c = datetime.datetime.today().year self.fecha_m = datetime.datetime.today() super(SabaticosEntidad, self).save(*args, **kwargs)

TIPO_FINANC = ( (01,'Gubernamental Federal'), (02,'Gubernamental Estatal'), (03,'Recursos del Extrangero'), )

Page 48: Desarrollo e implementación del Sistema de Información ...

4

8

class InstitucionesFinanciamiento(models.Model): id_sabatico = models.ForeignKey(SabaticosAcademicos, verbose_name="Sabatico Académico") tipo_financ = models.IntegerField('Tipo de financiamiento', choices=TIPO_FINANC) pais = models.ForeignKey(Pais, verbose_name="Pais", default=159) institucion = models.CharField('Institución', max_length=150)

5.7 B.6 Modelos de datos de la aplicación investigacion. #! /usr/bin/python # -*- coding: utf-8 -*- #----------------------------------------- # Mmodels.py de la app investigacion #----------------------------------------- from django.db import models from django.contrib.auth.models import User from siaa.generales.models import * from siaa.proyectos.models import Proyectos import datetime YEAR = datetime.datetime.now().year INDIZADO=( (1,'Indizado'), (2,'No indizado'), ) STATUS_ARTICULO=( (1,'Publicado'), (2,'En prensa'), (3,'Enviado'), ) ORIGEN = ( (1, 'Nacional'), (2, 'Extranjera'), ) TIPO_EDITOR =( (1,'Entidad'), (2,'Externo'), )

class Articulos(models.Model): indizado = models.IntegerField("Clasificación de la publicación", choices=INDIZADO) tipo_doc = models.ForeignKey(TipoDocumento, verbose_name="Tipo de publicación", related_name='FK_Iv_A_td') titulo = models.CharField('Título', max_length=300) autor = models.TextField('Lista completa de autores') autor_unam = models.TextField('Lista de autores UNAM', help_text='Tomar de la lista completa de autores, solo

aquellos que pertenecen a la UNAM') nom_abrev_revista = models.ForeignKey(Revistas, verbose_name='Revista', help_text='Nombre abreviado de la

revista', related_name='FK_Iv_A_nar') si_otra = models.CharField ('Especificar nombre de la revista', max_length=100, null=True, blank=True,

help_text="En caso de elegir la opción otro. ") estatus = models.IntegerField('Estatus', choices=STATUS_ARTICULO) electronic_only = models.BooleanField('Solo electrónico') year = models.IntegerField('Año', default=YEAR) volumen = models.IntegerField('Volúmen', null=True, blank=True) numero = models.IntegerField('Número', null=True, blank=True) pagina_ini = models.IntegerField('de la', null=True, blank=True) pagina_fin = models.IntegerField('a la', null=True, blank=True) doi = models.CharField('DOI', max_length=50, null=True, blank=True) bibcode = models.CharField(max_length=100, null=True, blank=True) #Campos de control ---> propietario = models.ForeignKey(User, null=True, blank=True, related_name='Iv_A_p') fecha_c = models.DateField(editable=False, null=True, blank=True) fecha_m = models.DateField(null=True, blank=True) year_c = models.IntegerField('Año de reporte', editable=False, null=True, blank=True) class Meta: ordering= ['titulo']

Page 49: Desarrollo e implementación del Sistema de Información ...

4

9

verbose_name='Articulo de investigación' verbose_name_plural='Artículos de investigación' def __unicode__(self): return self.titulo def save(self, *args, **kwargs): ''' On save, update timestamps''' if not self.id: self.fecha_c = datetime.datetime.today() if datetime.datetime.today().month == 01: self.year_c = datetime.datetime.today().year-1 else: self.year_c = datetime.datetime.today().year self.fecha_m = datetime.datetime.today() super(Articulos, self).save(*args, **kwargs) class ArtIndices(models.Model): articulo = models.ForeignKey(Articulos) indice = models.ForeignKey(IndicesArbitraje, verbose_name='Índice') def __unicode__(self): return "" class Memorias(models.Model): titulo = models.CharField('Título del trabajo', max_length=300) memoria = models.CharField('Memoria o evento', max_length=300) autor = models.TextField('Lista completa de autores') autor_unam = models.TextField('Lista de autores UNAM', help_text='Tomar de la lista completa de autores, solo

aquellos que pertenecen a la UNAM') editores = models.CharField('Editores', max_length=100) editorial = models.CharField('Editorial', max_length=200, null=True, blank=True) estatus = models.IntegerField('Estatus', choices=STATUS_ARTICULO) indices = models.CharField(default='ADS', max_length=30, help_text="Separar con comas en caso de ser mas de un

indice.") origen = models.IntegerField('Origen de la publicación', choices=ORIGEN) year = models.IntegerField('Año', default=YEAR) pagina_ini = models.IntegerField('de la', null=True, blank=True) pagina_fin = models.IntegerField('a la', null=True, blank=True) volumen = models.IntegerField('Volúmen', null=True, blank=True) numero = models.IntegerField('Número', null=True, blank=True) editorial = models.CharField('Editorial', max_length=200, null=True, blank=True) isbn = models.CharField('ISSN o ISBN', max_length=30, null=True, blank=True) #Campos de control ---> propietario = models.ForeignKey(User, null=True, blank=True, related_name='Iv_M_p') fecha_c = models.DateField(editable=False, null=True, blank=True) fecha_m = models.DateField(null=True, blank=True) year_c = models.IntegerField('Año de reporte', editable=False, null=True, blank=True) class Meta: ordering= ['titulo'] verbose_name='Articulo en extenso en memorias' verbose_name_plural='Artículos en extenso en memorias' def __unicode__(self): return self.titulo def save(self, *args, **kwargs): ''' On save, update timestamps''' if not self.id: self.fecha_c = datetime.datetime.today() if datetime.datetime.today().month == 01: self.year_c = datetime.datetime.today().year-1 else: self.year_c = datetime.datetime.today().year self.fecha_m = datetime.datetime.today() super(Memorias, self).save(*args, **kwargs) class Libros(models.Model): clasificacion = models.IntegerField() #CLASIFICACION Se asigna en el save() del admin titulo_libro = models.CharField('Título del libro', max_length=300) autor = models.TextField('Lista completa de autores') autor_unam = models.TextField('Lista de autores UNAM', help_text='Tomar de la lista completa de autores, solo

aquellos que pertenecen a la UNAM') pais_publicacion = models.ForeignKey(Pais, verbose_name='Pais', null=True, blank=True, default=159) ciudad_publicacion = models.CharField('Ciudad', max_length=100, null=True, blank=True)

Page 50: Desarrollo e implementación del Sistema de Información ...

5

0

casa_editorial = models.CharField('Casa(s) editorial(es)', max_length=200, null=True, blank=True) edicion = models.IntegerField(null=True, blank=True, default=1) anio_pub = models.IntegerField('Año de publicación', default=YEAR) paginas_tot = models.IntegerField('Páginas totales', null=True, blank=True) volumen = models.IntegerField('Volumén', help_text='Colección, Serie, Número ó Volumén', null=True, blank=True) isbn = models.CharField('ISBN', max_length=30, null=True, blank=True) #Campos de control ---> propietario = models.ForeignKey(User, null=True, blank=True, related_name='Iv_L_p') fecha_c = models.DateField(editable=False, null=True, blank=True) fecha_m = models.DateField(null=True, blank=True) year_c = models.IntegerField('Año de reporte', editable=False, null=True, blank=True) class Meta: ordering= ['titulo_libro'] verbose_name='Libro que has editado' verbose_name_plural='Libros que has editado' def __unicode__(self): return self.titulo_libro def save(self, *args, **kwargs): ''' On save, update timestamps''' if not self.id: self.fecha_c = datetime.datetime.today() if datetime.datetime.today().month == 01: self.year_c = datetime.datetime.today().year-1 else: self.year_c = datetime.datetime.today().year self.fecha_m = datetime.datetime.today() super(Libros, self).save(*args, **kwargs) class CapitulosLibros(models.Model): clasificacion = models.IntegerField() #CLASIFICACION Se asigna en el save() del admin titulo_libro = models.CharField('Título del libro', max_length=300) titulo_capitulo = models.CharField('Título del capítulo', max_length=300) autor = models.TextField('Lista completa de autores') autor_unam = models.TextField('Lista de autores UNAM', help_text='Tomar de la lista completa de autores, solo

aquellos que pertenecen a la UNAM') tipo_editor = models.IntegerField('Editor', choices=TIPO_EDITOR) pais_publicacion = models.ForeignKey(Pais, verbose_name='Pais', null=True, blank=True, default=159) ciudad_publicacion = models.CharField('Ciudad', max_length=100, null=True, blank=True) casa_editorial = models.CharField('Casa(s) editorial(es)', max_length=200, null=True, blank=True) edicion = models.IntegerField(null=True, blank=True, default=1) anio_pub = models.IntegerField('Año de publicación', default=YEAR) pagina_ini = models.IntegerField('de la', null=True, blank=True) pagina_fin = models.IntegerField('a la', null=True, blank=True) volumen = models.IntegerField('Volúmen', help_text='Colección, Serie, Número ó Volumén', null=True, blank=True) isbn = models.CharField('ISBN', max_length=30, null=True, blank=True) #Campos de control ---> propietario = models.ForeignKey(User, null=True, blank=True, related_name='Iv_CL_p') fecha_c = models.DateField(editable=False, null=True, blank=True) fecha_m = models.DateField(null=True, blank=True) year_c = models.IntegerField('Año de reporte', editable=False, null=True, blank=True) class Meta: ordering= ['titulo_capitulo'] verbose_name='Capítulo en libro' verbose_name_plural='Capítulos en libros' def __unicode__(self): return self.titulo_capitulo def save(self, *args, **kwargs): ''' On save, update timestamps''' if not self.id: self.fecha_c = datetime.datetime.today() if datetime.datetime.today().month == 01: self.year_c = datetime.datetime.today().year-1 else: self.year_c = datetime.datetime.today().year self.fecha_m = datetime.datetime.today() super(CapitulosLibros, self).save(*args, **kwargs) class ReportesTecnicos(models.Model): titulo_reporte = models.CharField('Título del reporte', max_length=300)

Page 51: Desarrollo e implementación del Sistema de Información ...

5

1

autor = models.TextField('Lista completa de autores') autor_unam = models.TextField('Lista de autores UNAM', help_text='Tomar de la lista completa de autores, solo

aquellos que pertenecen a la UNAM') instancias = models.TextField('Instancia(s)', help_text='Instancia(s) en la(s) que se publica', null=True,

blank=True) anio_elab = models.IntegerField('Año de elaboración', default=YEAR) paginas_tot =models.IntegerField('Total de páginas', null=True, blank=True) #Campos de control ---> propietario = models.ForeignKey(User, null=True, blank=True, related_name='Iv_RT_p') fecha_c = models.DateField(editable=False, null=True, blank=True) fecha_m = models.DateField(null=True, blank=True) year_c = models.IntegerField('Año de reporte', editable=False, null=True, blank=True) class Meta: ordering= ['titulo_reporte'] verbose_name='Reporte técnico' verbose_name_plural='Reportes técnicos' def __unicode__(self): return self.titulo_reporte def save(self, *args, **kwargs): ''' On save, update timestamps''' if not self.id: self.fecha_c = datetime.datetime.today() if datetime.datetime.today().month == 01: self.year_c = datetime.datetime.today().year-1 else: self.year_c = datetime.datetime.today().year self.fecha_m = datetime.datetime.today() super(ReportesTecnicos, self).save(*args, **kwargs) class OtrosResultados(models.Model): tipo_producto = models.ForeignKey(TipoResultados, verbose_name='Tipo de producto') nombre_producto = models.CharField('Nombre del producto', max_length=300) autor = models.TextField('Lista completa de autores') autor_unam = models.TextField('Lista de autores UNAM', help_text='Tomar de la lista completa de autores, solo

aquellos que pertenecen a la UNAM') #Campos de control ---> propietario = models.ForeignKey(User, null=True, blank=True, related_name='P_OR_p') fecha_c = models.DateField(editable=False, null=True, blank=True) fecha_m = models.DateField(null=True, blank=True) year_c = models.IntegerField('Año de reporte', editable=False, null=True, blank=True) class Meta: ordering= ['nombre_producto'] verbose_name='Otro resultado' verbose_name_plural='Otros Resultados' def __unicode__(self): return self.nombre_producto def save(self, *args, **kwargs): ''' On save, update timestamps''' if not self.id: self.fecha_c = datetime.datetime.today() if datetime.datetime.today().month == 01: self.year_c = datetime.datetime.today().year-1 else: self.year_c = datetime.datetime.today().year self.fecha_m = datetime.datetime.today() super(OtrosResultados, self).save(*args, **kwargs) class Autores(models.Model): articulo = models.ForeignKey(Articulos, blank=True, null=True) memoria = models.ForeignKey(Memorias, blank=True, null=True) libro = models.ForeignKey(Libros, blank=True, null=True) cap_libro = models.ForeignKey(CapitulosLibros, blank=True, null=True) rep_tec = models.ForeignKey(ReportesTecnicos, blank=True, null=True, related_name='FK_Iv_Au_rt') otros_res = models.ForeignKey(OtrosResultados, blank=True, null=True) autor = models.TextField('Lista completa de autores') es_unam = models.BooleanField('Es UNAM') class Meta:

Page 52: Desarrollo e implementación del Sistema de Información ...

5

2

ordering= ['autor'] verbose_name='Autor' verbose_name_plural='Autores' def __unicode__(self): #return self.autor return "" class ProyectosRelacionados(models.Model): proyecto = models.ForeignKey(Proyectos, verbose_name='Proyecto') articulo = models.ForeignKey(Articulos, blank=True, null=True) memoria = models.ForeignKey(Memorias, blank=True, null=True) libro = models.ForeignKey(Libros, blank=True, null=True) cap_libro = models.ForeignKey(CapitulosLibros, blank=True, null=True) rep_tec = models.ForeignKey(ReportesTecnicos, blank=True, null=True, related_name='FK_Iv_Pr_rt') otros_res = models.ForeignKey(OtrosResultados, blank=True, null=True) def __unicode__(self): return ""

5.8 B.7 Modelos de datos de la aplicación Proyectos. #! /usr/bin/python # -*- coding: utf-8 -*- #----------------------------------------- # Mmodels.py de la app Proyectos #----------------------------------------- from django.db import models from django.contrib.auth.models import User from django.db.models import Q from siaa.generales.models import * from siaa.academicos.models import Academicos import datetime if datetime.datetime.today().month == 1: YEAR = datetime.datetime.today().year - 1 else: YEAR = datetime.datetime.today().year STATUS_PROY =( (1, 'Nuevo'), (2, 'Proceso'), (3, 'Concluido'), ) T_PARTICIPACION = ( #(1, 'Responsable'), (2, 'Corresponsable'), (3, 'Participante'), ) class Proyectos(models.Model): clave_proyecto = models.CharField('Clave del proyecto', max_length=20, help_text='Clave o número del proyecto'

) nombre_proyecto = models.CharField('Nombre del proyecto', max_length=300) departamento = models.ForeignKey(Departamentos, verbose_name='Línea de investigación') anio_ini = models.IntegerField('Año de inicio', default=YEAR) responsable = models.ForeignKey(Academicos, verbose_name='Responsable') estatus = models.IntegerField('Estado del proyecto', choices=STATUS_PROY) clasificacion = models.ForeignKey(ClasificacionProy, verbose_name='Clasificación', null=True, blank=True) organizacion = models.ForeignKey(OrganizacionProy, verbose_name='Organización', null=True, blank=True) especialidades_wos = models.ForeignKey(EspecialidadesWoS, verbose_name='Especialidades de WoS', default=1,

null=True, blank=True) areas_wos = models.ForeignKey(AreasWoS, verbose_name='Áreas generales de WoS', default=23, null=True,

blank=True) impacto_social = models.ForeignKey(ImpactoSocial, verbose_name='Impacto Social', default=3, null=True,

blank=True) no_investigadores = models.IntegerField('Investigadores', default=0) no_academicos = models.IntegerField('Técnicos académicos', default=0) no_postdoc = models.IntegerField('Postdoctorados', default=0) no_doc = models.IntegerField('Alumnos de doctorado', default=0) no_maestria = models.IntegerField('Alumnos de maestría', default=0) no_licenciatura = models.IntegerField('Alumnos de Licenciatura', default=0) instituciones = models.TextField('Instituciones', help_text='Otras instituciones participantes', null=True,

blank=True) objetivo = models.TextField('Objetivo', null=True, blank=True)

Page 53: Desarrollo e implementación del Sistema de Información ...

5

3

#Campos de control ---> fecha_c = models.DateField(editable=False, null=True, blank=True) fecha_m = models.DateField(null=True, blank=True) year_c = models.IntegerField('Año de reporte', editable=False, null=True, blank=True) class Meta: ordering= ['nombre_proyecto'] verbose_name='Proyecto administrado por el CRyA' verbose_name_plural='Proyectos administrados por el CRyA (Responsable)' def __unicode__(self): return self.clave_proyecto + " - " + self.nombre_proyecto def save(self, *args, **kwargs): ''' On save, update timestamps''' if not self.id: self.fecha_c = datetime.datetime.today() if datetime.datetime.today().month == 01: self.year_c = datetime.datetime.today().year-1 else: self.year_c = datetime.datetime.today().year self.fecha_m = datetime.datetime.today() super(Proyectos, self).save(*args, **kwargs) class CorresponsablesProy(models.Model): proyecto = models.ForeignKey(Proyectos, blank=True, null=True) autor = models.CharField('Nombre', max_length=100) es_unam = models.BooleanField('UNAM', help_text="Seleccione la casilla si el autor pertenece a la UNAM") def __unicode__(self): return "" class ProyectosParticipacion(models.Model): clave_proyecto = models.ForeignKey(Proyectos, verbose_name='Proyecto') tipo_participacion=models.IntegerField(choices=T_PARTICIPACION) responsable_proyecto = models.CharField("Responsable", null=True, blank=True, max_length=100) #Campos de control ---> propietario = models.ForeignKey(User, null=True, blank=True, related_name='Iv_PP_p',

verbose_name='Participante') fecha_c = models.DateField(editable=False, null=True, blank=True) fecha_m = models.DateField(null=True, blank=True) year_c = models.IntegerField('Año de reporte', editable=False, null=True, blank=True) class Meta: ordering= ['propietario', 'clave_proyecto'] verbose_name='Proyecto' verbose_name_plural='Proyectos administrados por el CRyA (Participación)' def __unicode__(self): return self.clave_proyecto.clave_proyecto + " - " + self.clave_proyecto.nombre_proyecto def save(self, *args, **kwargs): ''' On save, update timestamps''' if not self.id: self.fecha_c = datetime.datetime.today() if datetime.datetime.today().month == 01: self.year_c = datetime.datetime.today().year-1 else: self.year_c = datetime.datetime.today().year self.fecha_m = datetime.datetime.today() self.responsable_proyecto = self.clave_proyecto.responsable super(ProyectosParticipacion, self).save(*args, **kwargs) class ProyectosObservacion(models.Model): clave_proyecto = models.CharField('Clave del proyecto', max_length=20, help_text='Clave o número del proyecto',

default="----", null=True, blank=True) nombre_proyecto = models.CharField('Nombre del proyecto', max_length=300) anio_ini = models.IntegerField('Año de inicio', default=YEAR) responsable = models.CharField('Responsable', max_length=50, null=True, blank=True) estatus = models.IntegerField('Estado del proyecto', choices=STATUS_PROY) no_investigadores = models.IntegerField('Investigadores', default=0) no_academicos = models.IntegerField('Técnicos académicos', default=0) no_postdoc = models.IntegerField('Postdoctorados', default=0) no_doc = models.IntegerField('Alumnos de doctorado', default=0) no_maestria = models.IntegerField('Alumnos de maestría', default=0)

Page 54: Desarrollo e implementación del Sistema de Información ...

5

4

no_licenciatura = models.IntegerField('Alumnos de Licenciatura', default=0) instituciones = models.TextField('Instituciones', help_text='Instituciones participantes', null=True,

blank=True) observatorio = models.TextField('Observatorio', help_text='Observatorio, telescopio o radiotescopio',

null=True, blank=True) objetivo = models.TextField('Objetivo', null=True, blank=True) #Campos de control ---> propietario = models.ForeignKey(User, verbose_name="Académico" ,null=True, blank=True, related_name='Iv_PO_p') fecha_c = models.DateField(editable=False, null=True, blank=True) fecha_m = models.DateField(null=True, blank=True) year_c = models.IntegerField('Año de reporte', editable=False, null=True, blank=True) class Meta: ordering= ['nombre_proyecto'] verbose_name='Proyecto de observación' verbose_name_plural='Proyectos de observación' def __unicode__(self): return self.nombre_proyecto def save(self, *args, **kwargs): ''' On save, update timestamps''' if not self.id: self.fecha_c = datetime.datetime.today() if datetime.datetime.today().month == 01: self.year_c = datetime.datetime.today().year-1 else: self.year_c = datetime.datetime.today().year self.fecha_m = datetime.datetime.today() super(ProyectosObservacion, self).save(*args, **kwargs) class ProyectosSupercomputo(models.Model): clave_proyecto = models.CharField('Clave del proyecto', max_length=20, help_text='Clave o número del proyecto',

default="----", null=True, blank=True) nombre_proyecto = models.CharField('Nombre del proyecto', max_length=300) anio_ini = models.IntegerField('Año de inicio', default=YEAR) responsable = models.CharField('Responsable', max_length=50, null=True, blank=True) estatus = models.IntegerField('Estado del proyecto', choices=STATUS_PROY) no_investigadores = models.IntegerField('Investigadores', default=0) no_academicos = models.IntegerField('Técnicos académicos', default=0) no_postdoc = models.IntegerField('Postdoctorados', default=0) no_doc = models.IntegerField('Alumnos de doctorado', default=0) no_maestria = models.IntegerField('Alumnos de maestría', default=0) no_licenciatura = models.IntegerField('Alumnos de Licenciatura', default=0) instituciones = models.TextField('Instituciones', help_text='Instituciones participantes', null=True,

blank=True) supercomputadora = models.TextField('Equipo', help_text='Equipo de supercomputo o procesamiento', null=True,

blank=True) objetivo = models.TextField('Objetivo', null=True, blank=True) #Campos de control ---> propietario = models.ForeignKey(User, verbose_name="Académico" ,null=True, blank=True,

related_name='Iv_PrSc_p') fecha_c = models.DateField(editable=False, null=True, blank=True) fecha_m = models.DateField(null=True, blank=True) year_c = models.IntegerField('Año de reporte', editable=False, null=True, blank=True) class Meta: ordering= ['nombre_proyecto'] verbose_name='Proyecto de supercómputo' verbose_name_plural='Proyectos de supercómputo' def __unicode__(self): return self.nombre_proyecto def save(self, *args, **kwargs): ''' On save, update timestamps''' if not self.id: self.fecha_c = datetime.datetime.today() if datetime.datetime.today().month == 01: self.year_c = datetime.datetime.today().year-1 else: self.year_c = datetime.datetime.today().year self.fecha_m = datetime.datetime.today() super(ProyectosSupercomputo, self).save(*args, **kwargs) class ProyectosInternacionales(models.Model): clave_proyecto = models.CharField('Clave del proyecto', max_length=20, help_text='Clave o número del proyecto',

default="----", null=True, blank=True)

Page 55: Desarrollo e implementación del Sistema de Información ...

5

5

nombre_proyecto = models.CharField('Nombre del proyecto', max_length=300) anio_ini = models.IntegerField('Año de inicio', default=YEAR) pais = models.ForeignKey(Pais, verbose_name="Pais", default=159) responsable = models.CharField('Responsable', max_length=50, help_text='Responsable en la institución

participante', null=True, blank=True) estatus = models.IntegerField('Estado del proyecto', choices=STATUS_PROY) no_investigadores = models.IntegerField('Investigadores', default=0) no_academicos = models.IntegerField('Técnicos académicos', default=0) no_postdoc = models.IntegerField('Postdoctorados', default=0) no_doc = models.IntegerField('Alumnos de doctorado', default=0) no_maestria = models.IntegerField('Alumnos de maestría', default=0) no_licenciatura = models.IntegerField('Alumnos de Licenciatura', default=0) instituciones = models.TextField('Instituciones', help_text='Instituciones participantes', null=True,

blank=True) objetivo = models.TextField('Objetivo', null=True, blank=True) financiado = models.TextField('Financiamiento', null=True, blank=True, help_text='Ingresar las institiciones

que finanacian el proyecto. Una por linea.') #Campos de control ---> propietario = models.ForeignKey(User, verbose_name="Académico" ,null=True, blank=True, related_name='Iv_PrI_p') fecha_c = models.DateField(editable=False, null=True, blank=True) fecha_m = models.DateField(null=True, blank=True) year_c = models.IntegerField('Año de reporte', editable=False, null=True, blank=True) class Meta: ordering= ['nombre_proyecto'] verbose_name='Otro proyecto' verbose_name_plural='Otros proyectos' def __unicode__(self): return self.nombre_proyecto def save(self, *args, **kwargs): ''' On save, update timestamps''' if not self.id: self.fecha_c = datetime.datetime.today() if datetime.datetime.today().month == 01: self.year_c = datetime.datetime.today().year-1 else: self.year_c = datetime.datetime.today().year self.fecha_m = datetime.datetime.today() super(ProyectosInternacionales, self).save(*args, **kwargs)

class ProyFinanciamiento(models.Model): proyecto = models.ForeignKey(Proyectos) fondo = models.ForeignKey(FondoFinanciamiento, verbose_name='Fondo', null=True, blank=True) tipo_apoyo = models.ForeignKey(TiposApoyo, verbose_name='Tipo de apoyo', limit_choices_to=

Q(id=2)|Q(id=4)|Q(id=5)) monto_solicitado = models.IntegerField('Monto solicitado', default=0) monto_asignado = models.IntegerField('Monto asignado', default=0) monto_ejercido = models.IntegerField('Monto ejercido', default=0) def __unicode__(self): return "" class ProyOtrosRecursos(models.Model): proyecto = models.ForeignKey(Proyectos) tipo_apoyo = models.ForeignKey(TiposApoyo, verbose_name="Tipo de apoyo") pais = models.ForeignKey(Pais, verbose_name="Pais", default=159) nom_institucion = models.CharField('Nombre de la institucion', max_length=200) monto_solicitado = models.IntegerField('Monto solicitado', default=0) monto_asignado = models.IntegerField('Monto asignado', default=0) monto_ejercido = models.IntegerField('Monto ejercido', default=0) def __unicode__(self): return "" class Convenios(models.Model): nombre_convenio = models.CharField('Nombre del convenio', max_length=300) responsable = models.ForeignKey(Academicos, verbose_name='Responsable') ambito = models.ForeignKey(Ambito, verbose_name='Ámbito del convenio', limit_choices_to= Q(ambito='Nacional')|

Q(ambito='Internacional')) objetivos = models.TextField ('Objetivos') fecha_inicio = models.DateField('Fecha de inicio') fecha_termino = models.DateField('Fecha de término') renovacion = models.BooleanField('Se trata de una renovacion') financiado = models.BooleanField('Incluye financiamiento')

Page 56: Desarrollo e implementación del Sistema de Información ...

5

6

firma = models.BooleanField(default=False) fecha_c = models.DateField(editable=False, null=True, blank=True) fecha_m = models.DateField(null=True, blank=True) year_c = models.IntegerField('Año de reporte', editable=False, null=True, blank=True) def save(self, *args, **kwargs): ''' On save, update timestamps ''' if not self.id: self.fecha_c = datetime.datetime.today() if datetime.datetime.today().month == 01: self.year_c = datetime.datetime.today().year-1 else: self.year_c = datetime.datetime.today().year self.fecha_m = datetime.datetime.today() super(Convenios, self).save(*args, **kwargs) class Meta: ordering=['nombre_convenio'] verbose_name='Convenio' verbose_name_plural='Convenios' def __unicode__(self): return self.nombre_convenio class InstitucionConvenio(models.Model): convenio = models.ForeignKey(Convenios) pais_institucion = models.ForeignKey(Pais, verbose_name='Pais', default=159) institucion = models.CharField('Institucion', max_length=250) class Meta: ordering=['convenio'] verbose_name='Institución' verbose_name_plural='Convenios' def __unicode__(self): return ""

5.9 B.8 Modelos de datos de la aplicación Vinculación. #! /usr/bin/python # -*- coding: utf-8 -*- #------------------------------- # Modelos de la app vinculacion #------------------------------- import datetime from django.db import models from django.db.models import Q #Importamos Q realizar querys personalizadas from django.contrib.auth.models import User #Importamos User, para utilizarlo como FK en los campos propietario from siaa.academicos.models import * #Importamos de la aplicacion academicos todos los modelos definidos para

utilizarlos como FK from siaa.generales.models import * if datetime.datetime.today().month == 01: YEAR = datetime.datetime.today().year-1 else: YEAR = datetime.datetime.today().year T_PARTICIPACION=( (1,'Plática'), (2,'Póster'), (3,'Revisión'), (4,'Solo asistencia'), ) class Arbitraje(models.Model): anio = models.IntegerField('Año', default=YEAR) publicacion = models.CharField ('Nombre de la publicación', max_length=200) indices = models.ForeignKey(IndicesArbitraje, verbose_name='Indice', default=3) dictamenes_anio = models.IntegerField('Dictamenes/año', default=0, help_text="Total de dictamenes en el año") #Campos de control ---> propietario = models.ForeignKey(User, verbose_name='Académico', null=True, blank=True) fecha_c = models.DateField(editable=False, null=True, blank=True) fecha_m = models.DateField(null=True, blank=True)

Page 57: Desarrollo e implementación del Sistema de Información ...

5

7

year_c = models.IntegerField('Año de reporte', editable=False, null=True, blank=True) def save(self, *args, **kwargs): ''' On save, update timestamps ''' if not self.id: self.fecha_c = datetime.datetime.today() if datetime.datetime.today().month == 01: self.year_c = datetime.datetime.today().year-1 else: self.year_c = datetime.datetime.today().year self.fecha_m = datetime.datetime.today() super(Arbitraje, self).save(*args, **kwargs) class Meta: ordering= ['anio'] verbose_name='Arbitraje' verbose_name_plural='Arbitrajes en revistas' def __unicode__(self): return self.publicacion class ArbitrajeProyectos(models.Model): anio = models.IntegerField('Año', default=YEAR) organismo = models.CharField('Solicitado por', max_length=300, help_text='Entidad que solicita el arbitraje') dict_anio = models.IntegerField('Dictamenes/año', default=0, help_text="Total de dictamenes en el año") #Campos de control ---> propietario = models.ForeignKey(User, null=True, blank=True, related_name='Pr_AP_p', verbose_name="Académico") fecha_c = models.DateField(editable=False, null=True, blank=True) fecha_m = models.DateField(null=True, blank=True) year_c = models.IntegerField('Año de reporte', editable=False, null=True, blank=True) def save(self, *args, **kwargs): ''' On save, update timestamps ''' if not self.id: self.fecha_c = datetime.datetime.today() if datetime.datetime.today().month == 01: self.year_c = datetime.datetime.today().year-1 else: self.year_c = datetime.datetime.today().year self.fecha_m = datetime.datetime.today() super(ArbitrajeProyectos, self).save(*args, **kwargs) class Meta: ordering= ['anio'] verbose_name='Arbitraje de proyectos' verbose_name_plural='Arbitrajes de proyectos' def __unicode__(self): return self.organismo class EvaluacionesAcademicas(models.Model): anio = models.DateField('Año', default=YEAR) organismo = models.CharField('Solicicitado por', max_length=300, help_text='Entidad que solicita la

evaluación') dict_anio = models.IntegerField('Evaluaciones/año', default=0, help_text="Total de evaluaciones en el año") #Campos de control ---> propietario = models.ForeignKey(User, null=True, blank=True, related_name='Pr_EA_p', verbose_name="Académico") fecha_c = models.DateField(editable=False, null=True, blank=True) fecha_m = models.DateField(null=True, blank=True) year_c = models.IntegerField('Año de reporte', editable=False, null=True, blank=True) def save(self, *args, **kwargs): ''' On save, update timestamps ''' if not self.id: self.fecha_c = datetime.datetime.today() if datetime.datetime.today().month == 01: self.year_c = datetime.datetime.today().year-1 else: self.year_c = datetime.datetime.today().year self.fecha_m = datetime.datetime.today() super(EvaluacionesAcademicas, self).save(*args, **kwargs) class Meta: ordering= ['anio']

Page 58: Desarrollo e implementación del Sistema de Información ...

5

8

verbose_name='Evaluación Académica' verbose_name_plural='Evaluaciones Académicas' def __unicode__(self): return self.organismo

class Eventos_Organizacion(models.Model): nombre_evento = models.CharField('Nombre del evento', max_length=300) tipo_evento = models.ForeignKey(TipoEvento, verbose_name='Tipo de evento') fecha_inicio = models.DateField('Fecha de inicio') fecha_termino = models.DateField('Fecha de término') lugar_pais = models.ForeignKey(Pais, verbose_name="País", default=159) lugar_ciudad = models.CharField('Ciudad', max_length=100) n_ponentes = models.IntegerField('Número de ponentes', default=0) n_asistentes = models.IntegerField('Número de asistentes', default=0) ambito = models.ForeignKey(Ambito, verbose_name='Ámbito')

#Campos de control ---> propietario = models.ForeignKey(User, verbose_name='Académico', null=True, blank=True) fecha_c = models.DateField(editable=False, null=True, blank=True) fecha_m = models.DateField(null=True, blank=True) year_c = models.IntegerField('Año de reporte', editable=False, null=True, blank=True) def save(self, *args, **kwargs): ''' On save, update timestamps ''' if not self.id: self.fecha_c = datetime.datetime.today() if datetime.datetime.today().month == 01: self.year_c = datetime.datetime.today().year-1 else: self.year_c = datetime.datetime.today().year self.fecha_m = datetime.datetime.today() super(Eventos_Organizacion, self).save(*args, **kwargs) class Meta: ordering=['nombre_evento'] verbose_name='Organización' verbose_name_plural='Organización de eventos académicos'

def __unicode__(self): return self.nombre_evento class eventos(models.Model): nombre_evento = models.CharField('Evento', max_length=300, help_text='Nombre del evento') tipo_evento = models.ForeignKey(TipoEvento, verbose_name='Tipo de evento', related_name='FK_V_EP_te') organiza_crya = models.BooleanField('Organizado por el CRyA') fecha = models.DateField('Fecha del evento', null=True, blank=True) lugar_pais = models.ForeignKey(Pais, verbose_name="País", default=159, related_name='FK_V_EP_p') lugar_ciudad = models.CharField('Ciudad y Estado', max_length=100, help_text='Ciudad y estado(provincia o

región)') #Campos de control ---> fecha_c = models.DateField(editable=False, null=True, blank=True) fecha_m = models.DateField(null=True, blank=True) year_c = models.IntegerField('Año de reporte', editable=False, null=True, blank=True) def __unicode__(self): return self.nombre_evento def save(self, *args, **kwargs): ''' On save, update timestamps ''' if not self.id: self.fecha_c = datetime.datetime.today() if datetime.datetime.today().month == 01: self.year_c = datetime.datetime.today().year-1 else: self.year_c = datetime.datetime.today().year self.fecha_m = datetime.datetime.today() super(eventos, self).save(*args, **kwargs) class Meta: ordering=['tipo_evento','nombre_evento']

Page 59: Desarrollo e implementación del Sistema de Información ...

5

9

verbose_name='Evento' verbose_name_plural='Eventos académicos autorizados' class presentaciones(models.Model): evento = models.ForeignKey(eventos, verbose_name = 'Evento', null = True, blank = True, related_name =

'FK_V_P_E', help_text="Seleccione un evento de la lista", default=None) evento_otro = models.CharField('Evento (otro)', max_length=300, null= True, blank= True, help_text='Indique el

nombre del evento, si no aparece en el listado anterior', default="Otro evento") tipo_evento = models.ForeignKey(TipoEvento, verbose_name='Tipo de evento', null= True, blank= True,

related_name='FK_V_Ev_te') organiza_crya = models.BooleanField('Organizado por el CRyA') titulo_presentacion = models.CharField('Título de la presentación', max_length=200, default="Sin título") tipo_particip = models.IntegerField('Tipo de participación', choices=T_PARTICIPACION) invitacion = models.BooleanField('Por invitación') n_asistentes = models.IntegerField('Número de asistentes', default=0) #Campos autollenados fecha = models.DateField('Fecha del evento', null=True, blank=True) pais = models.ForeignKey(Pais, verbose_name="País", default=159, related_name ="000-987", null = True, blank =

True) ciudad = models.CharField('Ciudad y Estado', max_length=100, help_text='Ciudad y estado(provincia o región)',

null= True, blank= True) #Campos de control ---> propietario = models.ForeignKey(User, verbose_name='Académico', null=True, blank=True,

related_name='FK_V_EP_pr') fecha_c = models.DateField(editable=False, null=True, blank=True) fecha_m = models.DateField(null=True, blank=True) year_c = models.IntegerField('Año de reporte', editable=False, null=True, blank=True) def __unicode__(self): return self.titulo_presentacion def save(self, *args, **kwargs): ''' On save, update timestamps ''' if not self.id: self.fecha_c = datetime.datetime.today() if datetime.datetime.today().month == 01: self.year_c = datetime.datetime.today().year-1 else: self.year_c = datetime.datetime.today().year self.fecha_m = datetime.datetime.today() super(presentaciones, self).save(*args, **kwargs) class Meta: ordering=['propietario','evento'] verbose_name='Asistencia/Presentación' verbose_name_plural='Asistencia y Presentaciones en eventos académicos' class Servicios(models.Model): nombre_servicio = models.CharField('Nombre del servicio', max_length=300) clasificacion = models.ForeignKey(TipoServicio, verbose_name='Clasificación') descripcion = models.TextField ('Descripción') dirigido_a = models.CharField('A quién va dirigido', max_length=50) tipo_institucion= models.ForeignKey(TipoInstitucion, verbose_name='Clasificación de la institución') anio_inicio= models.IntegerField('Año', default=YEAR, help_text="Año para el que se reporta") #Campos de control ---> propietario = models.ForeignKey(User, null=True, blank=True, related_name='V_S_p', verbose_name='Académico') fecha_c = models.DateField(editable=False, null=True, blank=True) fecha_m = models.DateField(null=True, blank=True) year_c = models.IntegerField('Año de reporte', editable=False, null=True, blank=True) def save(self, *args, **kwargs): ''' On save, update timestamps ''' if not self.id: self.fecha_c = datetime.datetime.today() if datetime.datetime.today().month == 01: self.year_c = datetime.datetime.today().year-1 else: self.year_c = datetime.datetime.today().year self.fecha_m = datetime.datetime.today() super(Servicios, self).save(*args, **kwargs) class Meta: ordering=['anio_inicio','nombre_servicio'] verbose_name='Asesoría' verbose_name_plural='Asesorías'

Page 60: Desarrollo e implementación del Sistema de Información ...

6

0

def __uniocode__(self): return self.nombre_servicio class Redes(models.Model): nombre_red = models.CharField('Nombre de la red', max_length=300) clasificacion = models.ForeignKey(Ambito, verbose_name='Clasificación de la red', limit_choices_to=~Q(id = 1)) regiones_participantes = models.TextField ('Regiones o paises que agrupa', max_length=100) objetivos = models.TextField ('Objetivos') anio_inicio= models.IntegerField('Año de constitución', default=YEAR) firma = models.BooleanField(default=False) fecha_c = models.DateField(editable=False, null=True, blank=True) fecha_m = models.DateField(null=True, blank=True) #Campos de control ---> propietario = models.ForeignKey(User, verbose_name='Académico', null=True, blank=True, related_name='V_R_p') fecha_c = models.DateField(editable=False, null=True, blank=True) fecha_m = models.DateField(null=True, blank=True) year_c = models.IntegerField('Año de reporte', editable=False, null=True, blank=True) def save(self, *args, **kwargs): ''' On save, update timestamps ''' if not self.id: self.fecha_c = datetime.datetime.today() if datetime.datetime.today().month == 01: self.year_c = datetime.datetime.today().year-1 else: self.year_c = datetime.datetime.today().year self.fecha_m = datetime.datetime.today() super(Redes, self).save(*args, **kwargs) class Meta: ordering=['anio_inicio','nombre_red', 'clasificacion'] verbose_name='Red' verbose_name_plural='Redes' def __uniocode__(self): return self.nombre_red SA_EVENTOS=( (1,'Curso'), (2,'Taller'), (3,'Diplomado'), (4,'Presentación'), ) class SuperacionAcademica(models.Model): nombre_evento = models.CharField('Evento', max_length=300, help_text='Nombre del evento al que asistió') tipo_evento = models.IntegerField('Tipo de evento', choices=SA_EVENTOS) fecha = models.DateField('Fecha del evento', null=True, blank=True) lugar_pais = models.ForeignKey(Pais, verbose_name="País", default=159, related_name='FK_V_EP_SA') lugar_ciudad = models.CharField('Ciudad y Estado', max_length=100, help_text='Ciudad y estado(provincia o

región)') invitacion = models.BooleanField('Por invitación') organiza_crya = models.BooleanField('Organizado por el CRyA') #Campos de control ---> propietario = models.ForeignKey(User, verbose_name='Académico', null=True, blank=True,

related_name='FK_V_EP_SA') fecha_c = models.DateField(editable=False, null=True, blank=True) fecha_m = models.DateField(null=True, blank=True) year_c = models.IntegerField('Año de reporte', editable=False, null=True, blank=True) def save(self, *args, **kwargs): ''' On save, update timestamps ''' if not self.id: self.fecha_c = datetime.datetime.today() if datetime.datetime.today().month == 01: self.year_c = datetime.datetime.today().year-1 else: self.year_c = datetime.datetime.today().year self.fecha_m = datetime.datetime.today() super(SuperacionAcademica, self).save(*args, **kwargs) class Meta: ordering=['nombre_evento'] verbose_name='Asistencia' verbose_name_plural='Superación Académica'

Page 61: Desarrollo e implementación del Sistema de Información ...

6

1

def __unicode__(self): return self.nombre_evento