Trabajo final de carrera Diseño de una aplicación Web para el control de los cultivos frutales. Ingenierı́a Técnica Informática de Sistemas Escuela Politécnica Superior Autor: Sergio Enrech Enrech Director: Josep Argelich Romà 29 de enero de 2013 Índice general 1. Introducción 11 1.1. Motivaciones . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 1.2. Objetivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 1.3. Contenido del documento . . . . . . . . . . . . . . . . . . . . 12 2. Análisis de requerimientos y planificación 2.1. Introducción . . . . . . . . . . . . . . . . . 2.2. Descripción de la aplicación web . . . . . . 2.3. Usuarios de la aplicación . . . . . . . . . . 2.4. Información básica de la aplicación . . . . 2.4.1. Parcelas . . . . . . . . . . . . . . . 2.4.2. Variedades frutales . . . . . . . . . 2.4.3. Trabajadores . . . . . . . . . . . . 2.4.4. Maquinaria . . . . . . . . . . . . . 2.4.5. Producción . . . . . . . . . . . . . 2.4.6. Jornada de trabajo . . . . . . . . . 2.4.7. Tratamientos . . . . . . . . . . . . 2.4.8. Gastos . . . . . . . . . . . . . . . . 2.5. Planificación temporal . . . . . . . . . . . 2.5.1. Tiempo real utilizado . . . . . . . . 2.5.2. Diagrama de Gantt . . . . . . . . . 2.6. Coste . . . . . . . . . . . . . . . . . . . . . 3. Diseño de la aplicación 3.1. Introducción . . . . . . . . . . . . . 3.2. Base de datos . . . . . . . . . . . . 3.2.1. Diagrama UML . . . . . . . 3.2.2. Traducción a Django Models 3.3. Vistas . . . . . . . . . . . . . . . . 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 15 15 16 16 16 17 17 17 18 18 18 18 18 19 20 20 . . . . . 25 25 25 26 26 29 Diseño de una aplicación Web para el control de los cultivos frutales 4. Tecnologı́a utilizada 4.1. Introducción . . . . 4.2. Python . . . . . . . 4.3. PHP . . . . . . . . 4.3.1. PHP PEAR 4.4. HTML . . . . . . . 4.5. CSS . . . . . . . . 4.6. JavaScript . . . . . 4.6.1. jQuery . . . 4.7. UML . . . . . . . . 4.8. MySQL . . . . . . 4.9. XML . . . . . . . . 4.10. LATEX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5. Django 5.1. Introducción . . . . . . . . . . . . . . . . . . . . 5.2. Caracterı́sticas . . . . . . . . . . . . . . . . . . 5.3. Proyectos y aplicaciones . . . . . . . . . . . . . 5.4. Fichero de configuración . . . . . . . . . . . . . 5.5. Arquitectura . . . . . . . . . . . . . . . . . . . . 5.5.1. Modelos . . . . . . . . . . . . . . . . . . 5.5.1.1. Tipos de campos (Field Types) 5.5.1.2. Relaciones . . . . . . . . . . . . 5.5.1.3. Interaccionar con los Modelos . 5.5.2. Plantillas . . . . . . . . . . . . . . . . . 5.5.3. URLs . . . . . . . . . . . . . . . . . . . 5.5.4. Vistas . . . . . . . . . . . . . . . . . . . 5.5.4.1. Plantillas en las Vistas . . . . . 5.5.5. Formularios . . . . . . . . . . . . . . . . 5.5.5.1. Creación de los formularios . . 5.5.5.2. Formularios en las vistas . . . . 5.5.5.3. Formularios sobre modelos . . . 5.5.5.4. Validación . . . . . . . . . . . . 5.5.6. Contenido Estático . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 33 33 34 35 35 35 36 36 36 37 37 38 . . . . . . . . . . . . . . . . . . . 41 41 41 42 44 45 45 45 46 49 51 52 53 53 54 55 56 57 57 58 6. Conclusiones 59 Apéndices 61 4 ÍNDICE GENERAL A. Extracción de datos para A.1. Introducción . . . . . . A.2. Uso de la API . . . . . A.3. Formato de salida . . . A.4. Código del Script . . . aplicaciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 externas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63 63 63 64 65 Índice de figuras 2.1. Diagrama Gantt 1 . . . . . . . . . . . . . . . . . . . . . . . . . 21 2.2. Diagrama Gantt 2 . . . . . . . . . . . . . . . . . . . . . . . . . 22 3.1. Diagrama UML . . . . . . . . . . . . . . . . . . . . . . . . . . 27 5.1. Vista jornadas . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 5.2. Formulario anadir produccion . . . . . . . . . . . . . . . . . . 56 7 Índice de cuadros 2.1. Tareas que componen el proyecto y duración en dı́as . . . . . 19 2.2. Comparativa entre la estimación y el coste real, en dı́as . . . 20 2.3. Coste de realizar la aplicación . . . . . . . . . . . . . . . . . . 23 5.1. Tipos en Django y equivalentes . . . . . . . . . . . . . . . . . 46 5.2. Equivalencias de campos entre Modelos y Formularios . . . . . 55 A.1. Comunidades Autónomas y sus códigos . . . . . . . . . . . . . 64 9 Capı́tulo 1 Introducción Hoy en dı́a surge la necesidad de que todo esté informatizado y correctamente ordenado. Una tarea tan manual como es la producción de fruta requiere de las modernas tecnologı́as, para ası́ hacer más sencillos los controles de productividad, calidad y fitosanitarios. Para tener un buen control sobre la producción y ganancias de una empresa agrı́cola, se ha de tomar nota diariamente de los trabajos realizados, ya sean recolección, poda o cualquier otra tarea desempeñada, pues en el campo se trabaja todo el año para producir unos meses. Por tanto es necesario llevar un control exhaustivo de la producción para ver si cubre los gastos de todo el año. También es necesario mantener un control sobre los tratamientos fitosanitarios o fertilizantes que se le dan a los árboles, ya que el Ministerio de Agricultura puede realizar inspecciones y necesitar esos datos para controlar la fruta. 1.1. Motivaciones La necesidad de realizar este proyecto surge de la relación con el campo desde niño. Casi todos los veranos de mi vida he trabajado con la fruta. De ahı́ surge la necesidad de crear este proyecto, para hacer algo útil para el gremio y particularmente para mi familia que se dedica a ello. La idea es crear una aplicación básica, sin muchas complicaciones, ya que en una empresa pequeña sin muchos medios, no se necesitan grandes aplicativos que precisen de gran cantidad de horas y recursos para llevar un control exhaustivo de la producción. Lo que necesita una empresa pequeña o familiar es una aplicación simple que requiera poco tiempo para introducir 11 Diseño de una aplicación Web para el control de los cultivos frutales la información en ella, pues la mayorı́a de las veces se introducirán datos al final de una jornada de trabajo. 1.2. Objetivos El objetivo principal de este proyecto es la creación de una aplicación en web, para la gestión de cultivos frutales. Para la creación de la aplicación se han definido los siguientes objetivos: Tener total control sobre la producción, de las distintas variedades de frutas cultivadas. Controlar las horas de trabajo, el lugar y la variedad recolectada por trabajadores de la empresa. Tener información detallada sobre todos los tratamientos aplicados a los árboles, ya sean fertilizantes, fitosanitarios, o simplemente riegos. Controlar gastos, especialmente los de la maquinaria usada. Poder acceder a la información de la base de datos de la aplicación desde fuera, para crear aplicaciones con las que acceder desde otros dispositivos. Por ejemplo desde teléfonos móviles. 1.3. Contenido del documento Este documento se estructura en 6 capı́tulos. Cada capı́tulo dispone de una breve introducción explicativa del tema que se irá ampliando a lo largo de las secciones del capı́tulo. Capı́tulo 1, Introducción: en el primer capı́tulo se exponen los objetivos, la introducción del proyecto y se da a conocer el contenido de los capı́tulos de este trabajo. Capı́tulo 2, Análisis de requerimientos: en este capı́tulo se estudian todas las necesidades del proyecto, se realiza una planificación temporal y una estimación del coste. Capı́tulo 3, Diseño de la aplicación: en este capı́tulo se explican los aspectos sobre el diseño de la base de datos y las funciones de vistas de la aplicación web. 12 Capı́tulo 1. Introducción Capı́tulo 4, Tecnologı́a utilizada: en este capı́tulo se explican todos los lenguajes de programación y distintas tecnologı́as utilizadas para la realización del proyecto. Capı́tulo 5, Django: Django es el framework web utilizado para la realización de la aplicación, en este capı́tulo se encuentra explicado el funcionamiento de Django. Capı́tulo 6, Conclusiones: en el último capı́tulo se explican las conclusiones del proyecto, ası́ como posibles mejoras que se le pudieran aplicar al trabajo. 13 Capı́tulo 2 Análisis de requerimientos y planificación 2.1. Introducción El objetivo principal es realizar una aplicación web para la gestión y el control de cultivos frutales. Una herramienta que permita gestionar todos los aspectos productivos y controlar en la medida de lo posible los aspectos externos que afectan directamente a la productividad de los árboles. 2.2. Descripción de la aplicación web La idea básica es que un usuario pueda acceder a la aplicación e introducir los datos sobre sus parcelas de cultivo y variedades frutales con las que trabaja, para luego ir añadiendo paulatinamente la producción y demás aspectos. Para llevar a cabo esto, dentro de la base de datos han de existir los campos de cultivo, que previamente alguien (el usuario) ha de dar de alta. La idea de la aplicación es que el usuario pueda controlar todo, por ello tendrá que tener registrado tanto los campos de cultivo mencionados, como las variedades de fruta que produce, los trabajadores, los tratamientos a los árboles, e incluso se le ha añadido a la aplicación la posibilidad de añadir la maquinaria usada, y gastos varios para ası́ poder tener un control total sobre productividad de la empresa. Nos encontramos ante una aplicación que necesita: Gestionar campos de cultivo y sus variedades de fruta. 15 Diseño de una aplicación Web para el control de los cultivos frutales Gestionar producción. Gestionar trabajadores, horas que trabajan y el lugar. Gestionar tratamientos a los árboles. Gestionar maquinaria agrı́cola. Gestionar gastos de mantenimiento. 2.3. Usuarios de la aplicación Existen tres tipos de usuarios en esta aplicación: Usuario o cliente: será el usuario que ceda a la web los datos de sus cultivos y controle todo lo que concierna a sus cultivos. Usuarios externos: la web dispone de una API (Application Programming Interface) que permite a usuarios externos a la aplicación recopilar datos, siempre anónimos, sobre producción de fruta en distintas zonas, para ası́ poder crear aplicaciones externas alrededor de este, también se pueden realizar estadı́sticas o ver que cultivos funcionan mejor en las distintas zonas de la geografı́a. Administrador: el administrador controlará los usuarios de la web. Cada usuario tiene sus funciones dentro de la aplicación y no podrá realizar funciones que no se le asignen. 2.4. Información básica de la aplicación Llegados a este punto, vemos que para realizar todo lo que hemos comentado necesitamos almacenar información sobre parcelas, variedades, maquinaria, etc. En los siguientes apartados podremos ver detalladamente todos los aspectos sobre los cuales se ha de almacenar información. 2.4.1. Parcelas Las parcelas son la superficie de terreno destinada a cultivar las variedades de fruta. Sobre ellas debemos almacenar una serie de datos referentes a la identificación del terreno. Para identificar rápidamente la parcela se 16 Capı́tulo 2. Análisis de requerimientos y planificación usará el nombre vulgar que el usuario desee darle y las coordenadas geográficas. También se almacenarán los parámetros de identificación del Sistema de Información Geográfica de Parcelas Agrı́colas (SIGPAC[1]) del Ministerio de Agricultura, Alimentación y Medio Ambiente. Los datos almacenados del SIGPAC tienen mucha utilidad para los agricultores, ya que sirven para rellenar multitud de impresos necesarios para realizar tramites con la administración, también sirve para los tramites de las subvenciones. La web del Ministerio dispone de un visor de mapas1 avanzado, en el que se pueden identificar las parcelas mediante fotos de satélite (orto-fotos) y realizar mediciones entre otras muchas funciones. 2.4.2. Variedades frutales Las variedades de fruta son una de las piezas principales de la aplicación, los usuarios se accederán a la web, para ingresar información sobre las variedades que trabajan. Es imprescindible que puedan ingresar toda información necesaria. Hace falta tener información básica de las variedades, como son la fecha de floración y recolección, también necesitaremos almacenar la producción y las horas de trabajo que le dedicamos, ası́ como los tratamientos fertilizantes o sanitarios que se le dan. También debemos controlar el precio que lleva la fruta para ver, a groso modo, si la empresa tiene beneficios o perdidas, pues la producción de fruta es la única fuente de ingresos. 2.4.3. Trabajadores En el apartado de los trabajadores se debe tener una ficha completa con todos los datos personales, fecha de inicio y final de contrato, y salario. Ası́ se puede tener un control de las horas que trabajan, ya que en el campo se suele cobrar por horas trabajadas. Cuando se dan de alta las jornadas de trabajo se deben especificar que trabajadores han trabajado en que parcelas para tener un control total. 2.4.4. Maquinaria La maquinaria son todos los vehı́culos como tractores, carretillas, coches y distintos aperos usados en las tareas agrı́colas sobre los que se debe llevar un control, ya que conllevan un gasto, ya sea de mantenimiento o averı́as que afecta al beneficio de la empresa. De las máquinas guardamos el nombre 1 Visor SIGPAC:http://sigpac.mapa.es/fega/visor/ 17 Diseño de una aplicación Web para el control de los cultivos frutales vulgar que le identifica, un tipo (coche, tractor, apero, etc.), la fecha de compra y una pequeña descripción. También se debe llevar un control sobre las averı́as y el mantenimiento. 2.4.5. Producción Producción entendemos como la cantidad, en kilogramos, de fruta recolectada. Para tener un absoluto control sobre la producción, debemos registrarla diariamente, indicando en que parcela, y que variedad se ha recolectado. 2.4.6. Jornada de trabajo La jornada de trabajo se entiende como las horas que se han trabajado en un dı́a para llevar a cabo cierta producción. Se debe dejar constancia diariamente, indicando en que parcela se ha llevado a cabo el trabajo, que variedad se ha recolectado, y que trabajadores han llevado a cabo la tarea. 2.4.7. Tratamientos Como tratamiento entendemos tanto los productos como el agua que se arrojan a los árboles para llevar a cabo una buena producción. Existen tres tipos de tratamiento, sobre los cuales debemos diferenciar: Fertilizante: son las sustancias, denominadas nutrientes, que sirven para potenciar las propiedades del suelo. Fitosanitario: los fitosanitarios o plaguicidas son aquellas sustancias o mezcla de ellas destinadas a prevenir o combatir plagas. Riego: es el agua que echamos el suelo para alimentar la tierra y los árboles. 2.4.8. Gastos Este apartado es para guardar otros gastos que tenga la empresa, ya sea compra de gasóleo para la maquinas, fertilizantes para los cultivos, etc. 2.5. Planificación temporal Para realizar la planificación temporal es necesario analizar la duración en dı́as de las diversas tareas que conforman el proyecto. La tabla 2.1 resume las tareas y su duración estimada. 18 Capı́tulo 2. Análisis de requerimientos y planificación Tarea Documentación Reuniones con profesionales del sector Diseño de la Base de Datos Reuniones con el director Documentación de Django Traducción de la base de datos a Django Creación de las vistas de Django Creación de los formularios Dar estilo a la página Creación de la API Redacción de la memoria Solución de problemas y retoques finales Preparación de la presentación Presentación Dı́as estimados 15 1 10 1 40 10 28 4 10 5 45 5 3 1 Cuadro 2.1: Tareas que componen el proyecto y duración en dı́as El proyecto se calculó con fecha de inicio 4 de Junio de 2012. Para calcular la estimación de fecha de finalización se creó un diagrama de Gantt que puede verse en el apartado 2.5.2. Tras realizar la planificación la fecha prevista de finalización pasó a ser el 27 de Septiembre de 2012. 2.5.1. Tiempo real utilizado Haciendo la comparativa entre el tiempo estimado y el tiempo real que ha costado, se ve que hay cierto desfase, tanto en fechas como en tiempo de algunas tareas. El proyecto no se empezó seriamente hasta Septiembre, por tanto existe un desfase en la fecha de inicio de 3 meses, pasando a ser 3 de Septiembre de 2012. Con la nueva fecha de inicio la fecha estimada en la planificación para la finalización se retrasa hasta el 27 de Diciembre. El proyecto es finalizado a finales de Enero, por tanto, la planificación quedó corta en un mes. La tabla 2.2 muestra la comparativa entre la estimación de coste, el coste real, y el desfase en dı́as de realizar el proyecto. 19 Diseño de una aplicación Web para el control de los cultivos frutales Tarea Estimados Trabajados Desfase Documentación 15 18 3 Reuniones con profesionales del sector 1 1 0 Diseño de la Base de Datos 10 15 5 Reuniones con el director 1 1 0 Documentación de Django 40 40 0 Traducción de la base de datos a Django 10 12 2 Creación de las vistas de Django 28 32 4 Creación de los formularios 4 6 2 Dar estilo a la página 10 16 6 Creación de la API 5 7 2 Redacción de la memoria 45 49 4 Solución de problemas y retoques finales 5 10 5 Preparación de la presentación 3 5 2 Presentación 1 1 0 Total 178 213 35 Cuadro 2.2: Comparativa entre la estimación y el coste real, en dı́as 2.5.2. Diagrama de Gantt Para poder hacer un cálculo estimado del tiempo que va a costar realizar el proyecto se ha creado un diagrama de Gantt ya que nos permite solapar tareas, programar tareas para que comiencen al finalizar otras, entre otras funciones. Para crear el diagrama se ha usado el software GanttProject[2] que es de libre distribución. Las figuras 2.1 y 2.2 muestran el diagrama de Gantt del proyecto subdividido en 4 partes, una por cada mes. 2.6. Coste Para calcular el coste de realizar la aplicación es necesario analizar el coste de los siguientes aspectos: Frameworks y distintos lenguajes de programación: todos los lenguajes utilizados y el Framework Django son de libre distribución, por tanto el coste es cero. 20 Capı́tulo 2. Análisis de requerimientos y planificación Figura 2.1: Diagrama Gantt 1 Dı́as de trabajo invertidos: una vez visto el número de dı́as trabajados en la planificación temporal, se ha calculado una media de 6 horas de trabajo al dı́a. Se ha establecido un precio de 20 euros por hora trabajada. Destacar también que en el proyecto ha habido muchas horas de documentación, sobre todo de Django, por tanto el coste puede quedar un poco hinchado, en un segundo proyecto Django no harı́an falta tantas horas de documentación. Con dı́as trabajados se refiere a dı́as laborables, no incluye fines de semana ni dı́as festivos. Puesta en funcionamiento: en este apartado se incluye la contratación de un dominio y el hosting de la web. Destacar que este es un gasto que se realizará anualmente. El hosting son unos 35 euros y el alquiler del domino unos 30 euros. En la estimación del coste de la aplicación solo se ha considerado el primer año de estos servicios. Ordenadores e internet: se ha creı́do conveniente contar con el precio 21 Diseño de una aplicación Web para el control de los cultivos frutales del ordenador ası́ como la conexión a Internet, pues han resultado ser herramientas imprescindibles para realizar el proyecto. Figura 2.2: Diagrama Gantt 2 La tabla 2.3 muestra el presupuesto, a groso modo, de realizar la aplicación. En ella vemos que el coste de realizar la aplicación asciende a 8695 euros. Hay que tener en cuenta que a la hora de crear la tabla de presupuesto, no se han considerado las reuniones ni la documentación, se ha reducido el número de dı́as en algunas tareas, pues algunas horas estaban dedicadas a la documentación. Solo se ha incluido el coste del primer año de hosting y el dominio, lo que serı́a la puesta en funcionamiento. 22 Capı́tulo 2. Análisis de requerimientos y planificación Concepto Horas de trabajo Ordenador ADSL Sistema Operativo (Linux) Framework Django Servidor MySQL pruebas Lenguajes de programación: Python PHP HTML CSS JavaScript y librerı́as jQuery UML MySQL XML LATEX Hosting Dominio Total Cantidad Precio Total 384 20 e/hora 7680 e 1 800 e 800 e 5 30 e/mes 150 e 1 0e 0e 1 0e 0e 1 0e 0e 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 35 30 Cuadro 2.3: Coste de realizar la aplicación 23 e e e e e e e e e e e 0 0 0 0 0 0 0 0 0 35 30 8695 e e e e e e e e e e e e Capı́tulo 3 Diseño de la aplicación 3.1. Introducción En esta sección se explica el diseño y la aplicación en si. La aplicación ha sido desarrollada con el framework web Django[3], basado en Python[5], por ello la mayor parte del código está escrito en Python. Django soporta diferentes motores de base de datos: PostgreSQL, MySQL, SQLite, PlSQL, etc. Entre todos se ha elegido MySQL[15] para la realización del proyecto. 3.2. Base de datos Para almacenar todos los requerimientos mencionados en el apartado 2.4 se han de modelar las siguientes clases en Django: Usuario: clase que modeliza a los usuarios de aplicación. Está formada por la información de la persona o empresa que vaya a utilizar la aplicación. Parcela: clase que modeliza los campos de cultivo. Contiene información de ubicación de la parcela y la información del Sistema de Información Geográfica. Variedad: clase que modeliza las variedades de fruta. Contiene las fechas de floración y recolección entre otros campos. Trabajador: clase que modeliza un trabajador. Contiene todos sus datos personales. Máquina: clase que modeliza la maquinaria agrı́cola. 25 Diseño de una aplicación Web para el control de los cultivos frutales Producción: clase que modeliza la producción en un dı́a concreto. Contiene instancia de la parcela y la variedad, ası́ como la fecha para indicar correctamente la producción. Jornada: clase que modeliza un dı́a de trabajo. Contiene la variedad, la parcela, la fecha y los trabajadores implicados, ası́ como las horas, y una descripción del trabajo realizado. Tratamiento: clase que modeliza un tratamiento a los árboles frutales. Discrimina entre tres tipos de tratamientos: riego, fitosanitarios y fertilizantes. Contiene instancias de Parcelas y Variedad ası́ como la fecha del tratamiento y una descripción de los productos utilizados en el caso de fitosanitarios o fertilizantes. PrecioFruta: modeliza el precio de la fruta en un rango de fechas. AveriaMantenimiento: modeliza las posibles costes de averı́as o trabajos de mantenimientos requeridos para el correcto funcionamiento de la maquinaria agrı́cola. Contiene una instancia de la máquina, la fecha y el coste. Trabaja: modeliza la relación entre un trabajador y la empresa en la que trabaja. MarcoPlantación: clase que modeliza el marco de plantación. Contiene instancia de Variedad y Parcela, la fecha de plantación ası́ como la fecha de arranque, y las distintas distancias entre árboles. Gastos: modeliza un cuadro básico con otros gastos que genera la empresa. 3.2.1. Diagrama UML Con las clases descritas en el apartado anterior se ha creado un diagrama UML que modeliza la base de datos. El diagrama se ha creado con el software de libre distribución Dia[4] lo podemos ver en la figura 3.1. 3.2.2. Traducción a Django Models Para modelar la base de datos en Django, primero hemos de traducir el diagrama de clases UML al modelo relacional. El resultado son las siguientes clases: 26 Capı́tulo 3. Diseño de la aplicación Figura 3.1: Diagrama UML 27 Diseño de una aplicación Web para el control de los cultivos frutales U s u a r i o ( id , r a z o n s o c i a l , d i r e c c i o n , m u n i c i p i o , cp , c i f , t e l e f o n o , fax , web ) P a r c e l a ( id , nombre , ca , p r o v i n c i a , m u n i c i p i o , agregado , poligono , parcela , recinto , latitud , longitud ) Variedad ( id , nombre , f e c h a r e c , f e c h a f l o r ) Trabajador ( id , nombre , a p e l l i d o s , d i r e c c i o n , m u n i c i p i o , p r o v i n c i a , cp , email , t e l e f o n o , dni , s e x o ) Maquina ( id , nombre , t i p o , fecha compra , d e s c r i p c i o n ) Producion ( i d p a r c e l a , i d v a r i e d a d , f e c h a , c a n t i d a d ) Tratamiento ( i d p a r c e l a , i d v a r i e d a d , f e c h a , t i p o , p r o d u c t o s ) PrecioFruta ( id variedad , f e c h a i n i , f e c h a f i n , precio ) GastoMaquinaria ( id maquina , f e c h a , horas , consumo , d e s c r i p c i o n ) AveriaMantenimiento ( id , maquina , f e c h a , c o s t e , d e s c r p c i o n , t i p o ) MarcoPlantacion ( i d p a r c e l a , i d v a r i e d a d , num arboles , dist arbol , dist fajeta , fecha plant , fecha fin ) Gastos ( id , concepto , f e c h a , c o s t e , d e s c r p c i o n ) A continuación debemos convertir estas clases a modelos de Django usando la clase models.Model, tal y como explica el capı́tulo 5. Por ejemplo la clase Variedad se traduce ası́: c l a s s Variedad ( models . Model ) : nombre = models . C h a r F i e l d ( max length =50) u s u a r i o = models . ForeignKey ( User ) f e c h a f l o r a c i o n = models . D a t e F i e l d ( ) f e c h a r e c o l e c c i o n = models . D a t e F i e l d ( ) def str ( self ): return s e l f . nombre def unicode ( self ): return s e l f . nombre Las clases con la clave primaria compuesta se deben modelar usando CompositeKeyModel del siguiente modo: c l a s s Pr od uc ci on ( CompositeKeyModel ) : i d = models . A ut o F ie l d ( p r i m a r y k e y=True ) p a r c e l a = models . ForeignKey ( P a r c e l a ) v a r i e d a d = models . ForeignKey ( Variedad ) f e c h a = models . D a t e F i e l d ( ) c a n t i d a d = models . P o s i t i v e I n t e g e r F i e l d ( ) c l a s s Meta : unique together = (( ’ parcela ’ , ’ variedad ’ , ’ fecha ’ ) ,) 28 Capı́tulo 3. Diseño de la aplicación 3.3. Vistas Una función de vista o una vista, como es conocida generalmente, 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, etc. Las vistas se han desarrollado según el manual de Django, tal y como describe el capı́tulo 5. A continuación se nombran todas las funciones de vistas clasificadas por funcionalidad: Funciones de vista principales de registro, login, etc: • principal • logout • portada Funciones de vistas generales, es decir, para listar todos los elementos de un modelo concreto con sus principales caracterı́sticas. Por ejemplo, trabajadores, variedades, etc. La nomenclatura de las vistas corresponde a la tabla de la base de datos que listan. • trabajadores • parcelas • variedades • maquinaria • producción • jornada • tratamiento • gastos Funciones para añadir elementos de una clase a la base de datos. La nomenclatura de las clases es: nuev[o—a] x o anadir x, donde x es la tabla a la que vamos a añadir elementos. Son las siguientes: • nuevo trabajador • nueva parcela • nueva variedad 29 Diseño de una aplicación Web para el control de los cultivos frutales • nueva maquina • nuevo tratamiento • nueva jornada • anadir produccion • nuevo precio • nueva plantacion • anadir mantenimiento • nuevo gasto Funciones para ver en detalle un elemento de una clase de la base de datos. La nomenclatura de estas funciones es la siguiente: ver x(x id), x es la tabla de la cual vamos a ver un elemento en detalle y id es el identificador del elemento de la tabla que vemos en detalle: • ver trabajador(id) • ver parcela(id) • ver variedad(id) • ver plantacion(id) • ver precios(id) • ver averia id(id) • ver mantenimiento(id) Funciones para editar elementos existentes en la base de datos. La nomenclatura de estas funciones es editar x donde x es la tabla de la cual vamos a editar elementos, id es el identificador del elemento que vamos a editar: • editar trabajador(id) • editar parcela(id) • editar produccion(id) • editar jornada(id) • editar variedad(id) • editar tratamiento(id) • editar plantacion(id) • editar gasto(id) 30 Capı́tulo 3. Diseño de la aplicación Funciones para eliminar elementos de la base de datos. La nomenclatura de las funciones de eliminar es eliminar x donde x es la tabla de la cual vamos a eliminar el elemento con identificador id. • eliminar produccion(id) • eliminar jornada(id) • eliminar tratamiento(id) • eliminar parcela(id) • eliminar variedad(id) • eliminar trabajador(id) • eliminar tratamiento(id) • eliminar gasto(id) Otras funciones con funcionamiento diferente: • ver averia(tipo id): esta función permite discernir entre los distintos tipos de averı́a. El tipo de averı́a (averı́a o mantenimiento) es pasado por parámetro a la función(tipo id ). • ver tratamiento(tipo id): esta función permite ver el tratamiento dependiendo del tipo. El tipo es pasado a la función por parámetro (tipo id)). • baja trabajador: esta función tiene la particularidad de que no elimina un trabajador, pone fecha a el campo de fin de contrato. 31 Capı́tulo 4 Tecnologı́a utilizada 4.1. Introducción Para la realización de este proyecto se utilizado diversas tecnologı́as. La principal es Python, pues el framework utilizado para realizar la aplicación, Django, está basado en este lenguaje. Para el diseño del diagrama de la base de datos se ha utilizado UML. Las plantillas de la web se han diseñado con HTML y hojas de estilo CSS. Para los widgets, como por ejemplo el calendario, el carrusel de imágenes, etc. se ha usado la librerı́a jQuery de JavaScript. También se ha utilizado PHP y su extensión PEAR para realizar la aplicación externa que se conecta a la base de datos(API) para recopilar datos. Esta aplicación retorna los datos en un archivo XML. Por ultimo para redactar este documento se ha utilizado el editor de textos cientı́ficos LATEX. En este capı́tulo se explican todas estas tecnologı́as utilizadas. 4.2. Python Python[5] es un lenguaje de programación interpretado1 creado por Guido van Rossum en 1991. Hoy en dı́a Python se desarrolla como un proyecto de código libre administrado por la fundación de software Python (Python 1 Lenguaje interpretado: No necesita compilarse 33 Diseño de una aplicación Web para el control de los cultivos frutales Software Foundation[6]). Python es un lenguaje multiparadigma. En vez de forzar a los programadores seguir un estilo concreto de programación, permite varios estilos: programación orientada a objetos, programación estructurada y programación funcional. Python se caracteriza por la indentación, tipos dinámicos y gestión automática de memoria. Una de las caracterı́sticas principales de Python es la sintaxis, que rápidamente salta a la vista. En Python los bloques de código se delimitan mediante el uso correcto de la indentación, en vez de con llaves. Esto implica que los espacios en blanco tienen significado y obliga a una correcta identación para el correcto funcionamiento, mejorando también la legibilidad del código. Python viene acompañado de un intérprete interactivo que permite agilizar el desarrollo de programas, pues sirve de banco de pruebas para probar las ideas y ası́ saber rápidamente su resultado. El intérprete Python es una de las mejores herramientas para aprender el lenguaje. 4.3. PHP PHP[7] (PHP: Hypertext Preprocessor), es un lenguaje de interpretado, de código abierto y de alto nivel, creado originalmente para el desarrollo web y el cual puede ser incrustado en páginas HTML. La finalidad de PHP es escribir páginas dinámicas de manera rápida y fácil. Sus principales caracterı́sticas son las siguientes: Es multiplataforma, es decir, puede ser utilizado en cualquier sistema operativo, sea Linux, Windows, Mac OS, Unix, etc. Soporta la mayorı́a de los servidores web de hoy en dı́a. Tiene soporte para una gran cantidad de sistemas de gestión de bases de datos. Es un lenguaje interpretado. El motor o intérprete es el que se encarga de recorrer el código PHP identificando las instrucciones y ejecutándolas. Se creó inicialmente para generar webs, especialmente webs dinámicas, sin embargo también podemos ejecutar scripts desde linea de coman34 Capı́tulo 4. Tecnologı́a utilizada dos o incluso generar aplicaciones de interfaz gráfica si utilizamos una extensión del lenguaje (PHP-GTK). El código PHP se integra fácilmente dentro de las sentencias HTML. Es capaz de generar no solo ficheros HTML, sino que también puede dar lugar a archivos de texto o incluso imágenes. 4.3.1. PHP PEAR PEAR[8] (PHP Extension and Application Repository) es un entorno de desarrollo y sistema de distribución para componentes de código PHP. Consiste en una lista bastante amplia de bibliotecas de código PHP que permiten hacer ciertas tareas de manera más rápida, eficiente y reutilizando código escrito previamente por otras personas. Generalmente las bibliotecas contienen clases en archivos PHP que se incluyen y se usan sencillamente. 4.4. HTML HTML[9] (HyperText Mark-up Language) es un lenguaje de marcado principalmente usado para la creación de páginas web. Se usa para describir y traducir la estructura y la información en forma de texto, ası́ como para ilustrar el texto con elementos como imágenes, vı́deos, etc. El código HTML se define mediante etiquetas (<et inicio> <\et fin>), que permiten añadir cualquier elemento a una página web. Permite también incluir scripts de otros lenguajes de programación como JavaScript o PHP, para ası́ permitir la creación de páginas dinámicas. 4.5. CSS CSS[10] (Cascading Style Sheets u Hojas de estilo en cascada) es un lenguaje formal que se utiliza para definir la presentación de un documento estructurado escrito en HTML o XML. El W3C (World Wide Web Consortium) es el organismo encargado de la especificación de las hojas de estilo que sirve como estándar. La idea que se encuentra detrás de las hojas CSS es separar la estructura de un documento de su presentación. Cuando se usa CSS, las etiquetas de los documentos HTML o XML no proporcionan información de como ha de ser 35 Diseño de una aplicación Web para el control de los cultivos frutales la presentación, sino que únicamente marcan la estructura del documento. La correspondiente hoja de estilo CSS se encarga de especificar como se ha de mostrar esa etiqueta: color, fuente, alineación del texto, etc. Algunas ventajas de usar CSS son: Se tiene un control centralizado de la presentación de la web que agiliza cualquier actualización. Los navegadores permiten a los usuarios usar su propia hoja de estilo, ası́ aumenta la accesibilidad. Por ejemplo: personas con deficiencias visuales pueden configurar su propia hoja de estilo, por ejemplo aumentando el tamaño del texto. Una página web puede disponer de diferentes hojas de estilo para diferentes dispositivos o para que el usuario pueda escoger. 4.6. JavaScript JavaScript[11] es un lenguaje de programación interpretado que se utiliza principalmente en páginas web. JavaScript permite la orientación a objetos. Todos los navegadores actuales interpretan el código JavaScript integrado en las páginas web. El código JavaScript se puede incluir en un documento HTML o en cualquier código que se acabe traduciendo a HTML en el navegador del cliente. El código JavaScript es visible y puede ser leı́do por el usuario ya que se ejecuta en el navegador del cliente. 4.6.1. jQuery JQuery[12] es una biblioteca de JavaScript que permite simplificar la manera de interactuar con los elementos HTML. Existen multitud de librerı́as en jQuery que aplican efectos a diversos elementos de las paginas web, como por ejemplo el carrusel de imágenes lightbox [13] usado en la web para obtener una mejor apariencia al maximizar las imágenes. 4.7. UML UML[14] (Unified Modeling Language) es un lenguaje de modelado de sistemas de software. Es un lenguaje gráfico para visualizar, especificar, construir y documentar un sistema. UML define un estándar para describir mo36 Capı́tulo 4. Tecnologı́a utilizada delos de bases de datos. El Lenguaje Unificado de Modelado (UML) prescribe un conjunto de notaciones y diagramas estándar para modelar sistemas orientados a objetos, y describe la semántica esencial de lo que estos diagramas y sı́mbolos significan. 4.8. MySQL MySQL[15] es un sistema de gestión de bases de datos relacional de código abierto. Su diseño multihilo le permite soportar una gran cantidad de información de forma muy eficiente. Entre las principales caracterı́sticas de MySQL se encuentran las siguientes: Gran capacidad para manejar con rapidez tanto volúmenes de datos grandes como pequeños. Aprovecha la potencia de sistemas multiprocesador, gracias a su implementación multihilo. Soporta gran cantidad de tipos de datos para las columnas. Dispone de API’s en gran cantidad de lenguajes (C, C++, Java, PHP, etc.). Gran portabilidad entre sistemas. Soporta hasta 32 ı́ndices por tabla. Gestión de usuarios y contraseñas, manteniendo un muy buen nivel de seguridad en los datos. Es multiplataforma, es decir, se puede usar en gran cantidad de sistemas operativos diferentes. 4.9. XML XML[16] (eXtensible Markup Language) es un lenguaje de marcas, desarrollado por el World Wide Web Consortium. Permite definir la gramática de lenguajes especı́ficos para estructurar documentos grandes. A diferencia de otros lenguajes, XML da soporte a bases de datos, siendo útil cuando varias 37 Diseño de una aplicación Web para el control de los cultivos frutales aplicaciones se deben comunicar entre sı́ o integrar información. XML no solo se creó para su aplicación en Internet, sino que nació con la idea de proponer un estándar para el intercambio de información estructurada entre diferentes plataformas. La estructura de un documento XML es la siguiente: <?xml v e r s i o n=” 1 . 0 ” e n c o d i n g=”UTF−8” ?> <!DOCTYPE E d i t M e n s a j e SYSTEM ” E d i t M e n s a j e . dtd ”> <Edit Mensaje > <Mensaje> <Remitente> <Nombre>Nombre del r e m i t e n t e </Nombre> <Mail> Correo del r e m i t e n t e </Mail> </Remitente> <D e s t i n a t a r i o > <Nombre>Nombre del d e s t i n a t a r i o </Nombre> <Mail>Correo del d e s t i n a t a r i o </Mail> </ D e s t i n a t a r i o > <Texto> <Asunto> Este e s mi documento con una e s t r u c t u r a muy s e n c i l l a no c o n t i e n e a t r i b u t o s n i e n t i d a d e s . . . </Asunto> <P a r r a f o > Este e s mi documento con una e s t r u c t u r a muy s e n c i l l a no c o n t i e n e a t r i b u t o s n i e n t i d a d e s . . . </P a r r a f o > </Texto> </Mensaje> </Edit Mensaje > 4.10. LATEX LATEX[17] es un sistema de composición de textos técnicos y cientı́ficos. El usuario únicamente tiene que preocuparse del contenido y no de la forma del documento. LATEX tiene un gran número de macros y estilos ya definidos, que facilitan la redacción de los documentos. Para redactar documentos en LATEX no es necesario disponer de ningún software en concreto, sólo en la compilación, ya que en cualquier editor de textos podemos empezar a redactar un documento LATEX. Una vez el documento está finalizado, se tiene que de compilar el fichero .tex. Al compilar podremos decidir si queremos que la 38 Capı́tulo 4. Tecnologı́a utilizada salida de nuestro documento sea en un formato DVI, PostScript o PDF. Se ha decidido el uso de LATEX para ası́ aprender un poco sobre este lenguaje de composición de textos. También porque para redactar un documento tan importante, otras herramientas como OpenOffice Writer o Microsoft Word no ofrecen resultados tan óptimos, y requieren un trabajo mucho más laborioso para obtener un estilo de texto óptimo. 39 Capı́tulo 5 Django 5.1. Introducción Django[3] es un framework de desarrollo web de código abierto escrito en Python. Inicialmente fue desarrollado para gestionar varias páginas orientadas a noticias. Se publicó bajo licencia BSD en Julio de 2005. En Julio de 2008 se creó la Django Software Foundation que se hizo cargo de Django para darle proyección en el futuro. 5.2. Caracterı́sticas El principal objetivo de Django es facilitar la creación de sitios web complejos. Django se centra en la automatización y en reutilizar componentes, haciendo énfasis del principio DRY (Don’t Repeat Yourself, algo ası́: No te repitas) Las principales caracterı́sticas de Django son las siguientes: Mapeador objeto-relacional: las clases del modelo (base de datos) se definen en Python y se trabaja con la API de acceso a la base de datos que provee Django. Esto permite desarrollar independientemente el motor de la base de datos y evita en cierta medida el uso de SQL. Vistas genéricas: incorpora un sistema de vistas genéricas para hacer tareas habituales: listar registros, ver el detalle de un registro, borrar un registro, etc. URLs elegantes: permite crear URLs elegantes y limpias haciendo 41 Diseño de una aplicación Web para el control de los cultivos frutales servir expresiones regulares1 Sistema de plantillas: incorpora un sistema de plantillas que permite separar diseño gráfico y programación. Se puede editar el HTML sin tocar el código Python. Cache: usa memcached2 para obtener buen rendimiento. Aplicaciones pluggables: las aplicaciones se pueden instalar en cualquier otro proyecto Django, es decir, son reutilizables 5.3. Proyectos y aplicaciones Los proyectos de Django se dividen en aplicaciones. Un proyecto Django contiene al menos una aplicación. Una aplicación de Django es un aplicación web que realiza una tarea concreta (un blog, un catalogo, etc.), un proyecto es una colección de aplicaciones configuradas de una determinada forma para un sitio web. Un proyecto puede contener varias aplicaciones y una aplicación puede estar en varios proyectos. La estructura de un proyecto es la siguiente: agroGestion / manage . py agroGestion / init . py models . py v i e w s . py Estos ficheros son: manage.py: es una utilidad de lı́nea de comandos, sirve para administrar o interactuar con el proyecto. agroGestion/ init .py:: fichero vacı́o que indica al intérorete de Python que este directorio se ha de considerar como un paquete de Python. agroGestion/settings.py: es el fichero de configuración para el proyecto Django. 1 2 Expresiones regulares: http://es.wikipedia.org/wiki/Expresion_regular Memcached: http://es.wikipedia.org/wiki/Memcached 42 Capı́tulo 5. Django agroGestion/urls.py: fichero de configuración de URLs del proyecto. agroGestion/wsgi.py: punto de entrada para servidores web WSGI3 compatibles con el proyecto. Dentro de cada proyecto hay una o varias aplicaciones. Cada una consiste en un paquete Python que sigue una estructura, la siguiente: agroGestion / agroWeb/ init . py s e t t i n g s . py u r l s . py w s g i . py forms . py admin . py Los nombres de los ficheros indican cual es su función: init .py: igual que en el proyecto, su función es indicar que el directorio es un paquete Python. models.py: en este fichero se definen los modelos de la aplicación. views.py: fichero donde se definen las funciones de vistas. forms.py: fichero para la definición de los formularios. Es opcional ya que los formularios pueden definirse en views.py admin.py: fichero para la definición de la interfaz automática de administración. La principal ventaja de dividir un proyecto en aplicaciones es que estas se pueden utilizar en otros proyectos4 . Django tiene varias aplicaciones instaladas por defecto: django.contrib.auth: un sistema de autenticación a partir de usuarios, grupos y permisos. django.contrib.admin: una interfaz web de administración que permite interactuar con la base de datos. 3 4 Más info: https://docs.djangoproject.com/en/1.4/howto/deployment/wsgi/ En la web http://www.djangopackages.com/ pueden descargarse algunas aplicacio- nes. 43 Diseño de una aplicación Web para el control de los cultivos frutales django.contrib.sessions: aplicación que permite gestionar las sesiones. En el caso de este trabajo hay una única aplicación creada, agroWeb, que permite crear y gestionar todo relativo al cultivo de la fruta. 5.4. Fichero de configuración Toda la configuración de un proyecto de Django se guarda en un fichero, que se denomina settings.py y se guarda en la raı́z del proyecto. Para que Django funcione se ha de definir en el fichero manage.py la variable de entorno DJANGO SETTINGS MODULES e indicarle que fichero de configuración se está utilizando. En el fichero de configuración se pueden configurar muchas opciones de Django, por ejemplo: DEBUG = True USE I18N = True LANGUAGE CODE = ’ e s ’ # A c t i v a modo Debug ( True ) # A c t i v a c i o n d e l s o p o r t e I18N # Idioma por d e f e c t o #Datos de c o n e x i o n de l a b a s e de d a t o s : DATABASES = { ’ default ’ : { ’ENGINE ’ : ’ django . db . backends . mysql ’ ’NAME’ : ’ agroWeb ’ , ’USER ’ : ’ r o o t ’ , ’PASSWORD’ : ’ password ’ , ’HOST ’ : ’ ’ , ’PORT ’ : ’ ’ , } } TIME ZONE = ’ Europe / Madrid ’ # Zona h o r a r i a #A p l i c a c i o n e s i n s t a l a d a s en e l p r o y e c t o : INSTALLED APPS = ( ’ django . c o n t r i b . auth ’ , ’ django . c o n t r i b . s e s s i o n s ’ , ’ django . c o n t r i b . s t a t i c f i l e s ’ , ’ a g r o G e s t i o n . agroWeb ’ , ’ django . c o n t r i b . admin ’ , ) 44 ,# # # # Motor de l a BBDD Nombre de l a BBDD Usuario Cl a ve de a c c e s o Capı́tulo 5. Django En este fichero se deben definir parámetros como, las rutas donde se encuentran archivos estáticos, ya sean scripts de JavaScript, hojas de estilo CSS, o plantillas de Django, las funciones hash para encriptar la contraseña, la ruta donde se encuentran las plantillas, etc. En la documentación de Django se encuentran todas las opciones disponibles5 . 5.5. Arquitectura Django se basa en el Modelo Vista Controlador (MVC), aunque sus desarrolladores prefieren llamarlo Model Template View (MTV). El controlador pasa a ser la vista y la vista pasa a denominarse plantilla. En Django, una vista describe los datos que se ofrecen al usuario pero no necesariamente su aspecto. Una vista habitualmente delega los datos a una plantilla que describe la forma de presentarlos. Se dice que el controlador de un patrón MVC clásico estarı́a representado por el propio Framework. 5.5.1. Modelos Un modelo en Django es la descripción de un tipo de datos de nuestra aplicación, que se guardara en la base de datos, es decir, son las clases que necesitan persistir. Cada modelo se representa como una clase escrita en Python. La clase base, Model (django.db.models.Model) contiene todos los métodos necesarios para hacer que los objetos sean capaces de interactuar con la base de datos. Normalmente deja que las clases del modelo solo se hayan de ocupar de definir sus atributos. Habitualmente cada clase Model corresponde a una tabla de la base de datos, y cada atributo a una columna de la misma. 5.5.1.1. Tipos de campos (Field Types) Cada atributo es una instancia de una de las subclases de la clase django.db.models.Field. Django usa el tipo de estas clases para: Conocer el tipo de la columna de la base de datos. Crear la interfaz de administración automática. Validar el tipo de datos en formularios y en la administración. 5 http://docs.djangoproject.com/en/dev/ref/settings/ 45 Diseño de una aplicación Web para el control de los cultivos frutales Cada tipo de datos (atributo) tiene sus propios argumentos, unos son opcionales y otros son estrictamente obligatorios. Por ejemplo, el tipo CharField tiene el argumento obligatorio max length, que especifica la medida del campo Varchar de MySQL en la base de datos. En la documentación de Django se pueden encontrar todos los tipos de datos con sus atributos 6 . Django también permite definir nuevos tipos de datos. Los tipos de datos más comunes los podemos ver en la tabla 5.1. Clase en Django BooleanField CharField DateField DecimalField IntegerField TextField Tipo en Python bool str datetime.date float int str Tipo en SQL TINYINT VARCHAR DATE DECIMAL INT TEXT Cuadro 5.1: Tipos en Django y equivalentes A continuación se expone un ejemplo de como declarar una clase: from django . db import models c l a s s P a r c e l a ( models . Model ) : nombre = models . C h a r F i e l d ( max length =50) ca = models . ForeignKey (CA) p r o v i n c i a = models . ForeignKey ( P r o v i n c i a ) m u n i c i p i o = models . ForeignKey ( M u n i c i p i o ) a g r e g a d o = models . I n t e g e r F i e l d ( ) p o l i g o n o = models . I n t e g e r F i e l d ( ) p a r c e l a = models . I n t e g e r F i e l d ( ) Si el modelo no tiene un atributo declarado como clave primara, Django asigna una clave auto numérica accesible mediante el atributo id. 5.5.1.2. Relaciones Las bases de datos relacionales permiten relacionar las tablas entre si. Django permite modelar las relaciones más comunes: 6 http://docs.djangoproject.com/en/dev/ref/models/fields 46 Capı́tulo 5. Django 1. Uno a Varios (Many to One): Para definir relaciones uno a varios se usa ForeignKey, igual que declaramos cualquier tipo de datos. ForeignKey necesita un argumento, que es el nombre de la tabla a la que referencia: from django . db import models c l a s s Variedad ( models . Model ) : # ... c l a s s P r e c i o F r u t a ( models . Model ) : v a r i e d a d = models . ForeignKey ( Variedad ) # ... 2. Muchos a Muchos (Many to Many): Para definir relaciones de muchos a muchos se usa ManyToManyField. Da igual en que clase se defina la relación, el resultado es el mismo aunque solo hay que definirlo en una de las dos. from django . db import models c l a s s Variedad ( models . Model ) : # ... c l a s s P r e c i o F r u t a ( models . Model ) : v a r i e d a d = models . ManyToManyField ( Variedad ) # ... 3. Uno a Uno (One to One): Las relaciones uno a uno se definen como los casos anteriores con el tipo OneToOneKey. 4. Relaciones ternarias, cuaternarias, etc. A dı́a de hoy Django no dispone de ningún método para modelar estas relaciones. Sin embargo usuarios de Django proponen una solución, CompositeKeyModel7 que permite definir relaciones ternarias, cuaternarias, etc. Consiste en definir una clase al principio del fichero models.py que hace de modelo para estas relaciones. La clase en cuestión es la siguiente: c l a s s CompositeKeyModel ( models . Model ) : pass 7 https://code.djangoproject.com/ticket/373 47 Diseño de una aplicación Web para el control de los cultivos frutales c l a s s I n t e r m e d i a t e M o d e l B a s e ( ModelBase ) : def n e w ( c l s , name , b a s e s , a t t r s ) : i f CompositeKeyModel in b a s e s : i f b a s e s == ( CompositeKeyModel , ) : n e w c l a s s = ModelBase . n e w ( ModelBase , name , ( models . Model , ) , a t t r s ) newclass . b a s e s = ( CompositeKeyModel , ) return n e w c l a s s e l s e : r a i s e Exception , ” NotSuportMoreThanOneDatabase ” else : return type . n e w ( c l s , name , b a s e s , a t t r s ) c l a s s CompositeKeyModel ( models . Model ) : metaclass = IntermediateModelBase def s a v e ( s e l f , ∗ a r g s , ∗∗ kwargs ) : f i l t e r = {} i f not s e l f . meta . u n i q u e t o g e t h e r : raise ValueError ( ’ u n i qu e t o g et h e r t o emulate Composite pk ’ ) f o r f i e l d n a m e l i s t in s e l f . meta . u n i q u e t o g e t h e r : f o r f i e l d in f i e l d n a m e l i s t : f i l t e r [ f i e l d ]= ’ %s ’ % ( s e l f . g e t f i e l d v a l u e ( f i e l d ) ) fetched = s e l f . class . objects . complex filter ( f i l t e r ) i f ( len ( fetched ) > 0): pk = s e l f . g e t p r i m a r y k e y ( ) s e l f . s e t a t t r ( pk . name , fetched [ 0 ] . g e t a t t r i b u t e ( pk . name ) ) models . Model . s a v e ( s e l f , ∗ a r g s , ∗∗ kwargs ) def i s f o r e i g n k e y ( s e l f , f i e l d ) : meta class = getattr ( f i e l d . c l a s s ’ m e t a c l a s s ’ , None ) return m e t a c l a s s == ModelBase , def g e t f i e l d v a l u e ( s e l f , f i e l d N a m e ) : f i e l d v a l u e = g e t a t t r ( s e l f , fieldName ) if self . is foreign key ( field value ): return f i e l d v a l u e . pk return f i e l d v a l u e def g e t p r i m a r y k e y ( s e l f ) : f o r f i e l d in s e l f . meta . f i e l d s : i f ( f i e l d . primary key ) : return f i e l d r a i s e E x c e p t i o n ( ’ Your model must have a dummy 48 Capı́tulo 5. Django primary key ( i d ) ’ ) Una vez definida la clase CompositeKeyModel al principio del fichero models.py La manera de definir la relación pasa a ser la siguiente: c l a s s Pr od uc ci on ( CompositeKeyModel ) : i d = models . A ut o F ie l d ( p r i m a r y k e y=True ) p a r c e l a = models . ForeignKey ( P a r c e l a ) ) v a r i e d a d = models . ForeignKey ( Variedad ) f e c h a = models . D a t e F i e l d ( ) c a n t i d a d = models . P o s i t i v e I n t e g e r F i e l d ( ) c l a s s Meta : unique together = (( ’ parcela ’ , ’ variedad ’ , ’ fecha ’ ) ,) En esta relación hemos de crear una clase Meta donde le pasamos los parámetros que van a componer la clave primaria. También hemos de definir manualmente un id para la clave primaria. 5.5.1.3. Interaccionar con los Modelos Django proporciona una API que permite interaccionar con los Modelos sin necesidad de usar código SQL, aunque para sentencias complejas permite el uso de código SQL. Creación de objetos Para crear nuevos objetos hemos de crear una instancia de una clase y llamar al método save() para guardarla. El valor de los atributos pueden especificarse en el método constructor o accediendo después a los atributos de la clase. from a g r o G e s t i o n . agroWeb . models import Variedad p = Variedad ( name= ’ Nombre ’ , f e c h a p l= ’ 2008−03−04 ’ ) p . save ( ) Modificar objetos Se llama al método save() sobre una instancia ya existente que se actualiza en vez de crear una nueva. p . f e c h a f i n = ’ 2013−02−02 ’ p . save ( ) 49 Diseño de una aplicación Web para el control de los cultivos frutales Borrar objetos Para borrar se utiliza el método delete() p . delete () Obtener objetos Para obtener objetos hay distintos métodos: Obtener todos: para obtener todos los registros de un modelo se utiliza el método all(). v a r i e d a d e s = Variedad . o b j e c t s . a l l ( ) El atributo objects sirve para decir que nos devuelva una colección de objetos (QuerySet), es decir, que retorna una lista de objetos Variedad, en este caso. Filtrado de objetos: para obtener solo ciertos objetos, es decir, filtrar los que necesitamos se usan los siguientes métodos: • filter(**kwargs): devuelve los objetos que cumplen los requisitos de los parámetros pasados. • exclude(**kwargs): devuelve los objetos que no cumplen los requisitos de los parámetros pasados. Cada filtro recibe argumentos dentro de los paréntesis indicando los atributos que se deseen filtrar, por ejemplo: p = P a r c e l a . o b j e c t s . f i l t e r ( a g r e g a d o =1) También podemos combinar los filtros: p = P a r c e l a . o b j e c t s . f i l t e r ( a g r e g a d o =1). e x c l u d e ( r e c i n t o =3) Obtener un único objeto: para obtener un único objeto se utiliza el método get(). Este método obtiene un único resultado, y si la consulta retorna más de uno lanza una excepción. p = P a r c e l a . o b j e c t s . g e t ( i d =3) 50 Capı́tulo 5. Django 5.5.2. Plantillas Django proporciona un sistema de plantillas que permite separar la programación del diseño. El sistema de plantillas de Django está basado en la herencia, es decir, todo lo que deba ser común en todas se define en una plantilla base, que contendrá el esqueleto común, también se definirá con etiquetas los bloques donde las plantillas hijas puedan escribir. Las plantillas se pueden incluir dentro de la propia aplicación o bien en un único directorio aparte para todo el proyecto. Si lo hacemos de esta segunda forma debemos indicarle a Django donde las ubicamos en el fichero settings.py. A continuación se muestra un ejemplo del funcionamiento de las plantillas: < !DOCTYPE HTML PUBLIC ”−//W3C//DTD HTML 4 . 0 1 / / ES”> <html lang=” e s ”> <t i t l e> { % b l o c k t i t u l o %} { % e n d b l o c k %} </ t i t l e> </head> <body> <div id=” t i t u l o ”> <h2> AgroGestion </h2> </ div> <p id=” s a l i r ”><a href=” / l o g o u t ”> S a l i r</a></p> <div c l a s s=”menu”> <ul> < l i><a href=” / p o r t a d a / ”>Portada</a></ l i> < l i><a href=” / p a r c e l a s / ”>P a r c e l a s</a></ l i> < l i><a href=” / v a r i e d a d e s / ”>V a r i e d a d e s</a></ l i> . . . </ ul> </ div> { % b l o c k c o n t e n i d o %} { % e n d b l o c k %} </body> Esta plantilla, base.html, define el esqueleto HTML de nuestra aplicación. La estructura está dividida en dos partes, la parte del menú y la del contenido. Las plantillas que hereden de esta podrán rellenar contenido entre las etiquetas { % block contenido %} y { % end block %}. También podrán poner un tı́tulo personalizado dentro del bloque de tı́tulo. A continuación se muestra un ejemplo de una plantilla heredada de base.html : { % e x t e n d s ” b a s e . html ” %} 51 Diseño de una aplicación Web para el control de los cultivos frutales { % b l o c k t i t l e %} {{ t i t u l o }} { % e n d b l o c k %} { % b l o c k c o n t e n i d o %} <form method=”POST”> { % c s r f t o k e n %} {{ form . a s p }} <i n p u t type=” submit ” v a l u e=” Enviar ” /> </form> <form> </form> { % e n d b l o c k %} Como podemos observar esta plantilla del ejemplo hereda de base.html mediante la etiqueta { % extends ”base.html” %}. Dentro de las etiquetas de los bloques podemos poner contenido dinámico con etiquetas de las variables (entre doble clave {{ form.as p }}) que nos envı́a la función de vista. 5.5.3. URLs Uno de los factores a tener en cuenta a la hora de desarrollar una aplicación web son las URLs. Unas URLs limpias y amables son más fáciles de indexar por los creadores y más sencillas de recordar para los usuarios de la web. Django permite crear URLs totalmente personalizadas usando expresiones regulares y sin necesidad de que acaben en ”.html”, ”.php”, etc. Para diseñar las URLs se crea una tabla que mapea los patrones de las URLs (expresiones regulares) a las funciones de las vistas. Este mapeo se hace en el fichero urls.py. Un ejemplo serı́a el siguiente: from django . c o n f . u r l s . d e f a u l t s import ∗ from a g r o G e s t i o n . agroWeb . v i e w s import ∗ urlpatterns = patterns ( ’ ’ , u r l ( r ’ ˆ r e g i s t r o /$ ’ , r e g i s t r o ) , u r l ( r ’ ˆ l o g i n /$ ’ , l o g i n ) , url ( r url ( r url ( r url ( r ’ ˆ produccion /$ ’ , produccion ) , ’ ˆ produccion / anadir /$ ’ , anadir produccion ) , ’ ˆ p r o d u c c i o n / e d i t a r / ( ?P<p i d >\d+)/$ ’ , e d i t a r p r o d ) , ’ ˆ p r o d u c c i o n / e l i m i n a r / ( ?P<p i d >\d+)/$ ’ , e l i m i n a r p r o d ) , ) 52 Capı́tulo 5. Django Cuando Django recibe una petición, por ejemplo de 127.0.0.1:8000/login, determina cual es el modulo URLconf que ha de usar (especificado en settings.py), lo carga y busca la variable urlpatterns correspondiente. Cuando la expresión regular coincida, Django llama a la vista que corresponde. En este caso llamarı́a a la función vista login. 5.5.4. Vistas Las vistas en Django son funciones en Python que equivalen a controladores en una arquitectura MVP tradicional. Una vista recibe una petición (request) y devuelve una respuesta (response). La respuesta puede ser el contenido HTML de una página, una redirección a otra página (redirect), un error 404, etc. Un ejemplo de vista sencilla es el siguiente: from django . h t t p import HttpResponse import d a t e t i m e def c u r r e n t d a t e t i m e ( r e q u e s t ) : now = d a t e t i m e . d a t e t i m e . now ( ) html = ”<html><body>Hoy e s %s .</body></html> %now” return HttpResponse ( html ) Esta función hace una petición de la fecha actual y devuelve un objeto HttpResponse que contiene la respuesta HTML. Todas vistas han de retornar un objeto de la clase HttpResponse o de alguna de sus subclases como HttpResponseNotFound, HttpResponseRedirect, etc. En la imagen 5.1 podemos ver como queda una vista, en este caso es de la función jornadas. 5.5.4.1. Plantillas en las Vistas Al contrario que el ejemplo anterior (Vistas) la filosofı́a de Django es editar el código Python para cambiar la maquetación de la página. Para separar el diseño del código se usa el sistema de plantillas. from django . t e m p l a t e . l o a d e r import g e t t e m p l a t e from django . t e m p l a t e import Context from django . h t t p import HttpResponse import d a t e t i m e def c u r r e n t d a t e t i m e ( r e q u e s t ) : 53 Diseño de una aplicación Web para el control de los cultivos frutales now = d a t e t i m e . d a t e t i m e . now t = g e t t e m p l a t e ( ’ c u r r e n t d a t e t i m e . html ’ ) html = t . r e n d e r ( Context ( { ’ c u r r e n t d a t e ’ : now } ) ) return HttpResponse ( html ) Este código carga la plantilla current datetime.html, a la que se le pasa un contexto. El contexto es un diccionario que mapea las variables de la plantilla a variables Python. La plantilla podrı́a ser la siguiente: <html> <body> <p> Hoy e s {{ c u r r e n t d a t e }} </p> </body> </html> Las etiquetas entre corchetes son las variables de la plantilla, que se sustituyen por las variables de contexto. En este caso la etiqueta current date se sustituirı́a por la variable Python now. Figura 5.1: Vista jornadas 5.5.5. Formularios En una aplicación web con base de datos, es imprescindible que existan formularios para poder insertar los datos en la aplicación. Django provee una librerı́a para definir los formularios, con la que podemos, además de definir 54 Capı́tulo 5. Django todos los campos de los formularios, mostrar formularios con widgets (clase que corresponde a un widget de un formulario HTML) generados automáticamente, comprobar los datos presentados frente a unas reglas de validación, volver a mostrar un formulario en caso de errores de validación, convertir los datos de un formulario a tipos de Python, etc. Django define una serie de campos para los distintos tipos de datos en los formularios. Estos son similares a los campos de los modelos. Los principales los podemos ver en la tabla 5.2. Model field BooleanField CharField DateField DecimalField EmailField ForeignKey IntegerField ManyToManyField Form field BooleanField CharField con max length igual que en el modelo DateField DecimalField EmailField ModelChoiceField IntegerField ModelMultipleChoiceField Cuadro 5.2: Equivalencias de campos entre Modelos y Formularios 5.5.5.1. Creación de los formularios Los formularios se pueden definir en el mismo fichero que las vistas, aunque por claridad es recomendable crear un fichero forms.py en el directorio raı́z de la aplicación. Definir los formularios es similar a la definición de las vistas. from django import forms c l a s s ContactForm ( forms . Form ) : s u b j e c t = forms . C h a r F i e l d ( max length =100) message = forms . C h a r F i e l d ( ) s e n d e r = forms . E m a i l F i e l d ( ) c c m y s e l f = forms . B o o l e a n F i e l d ( r e q u i r e d=F a l s e ) En la imagen 5.2 podemos ver como queda un formulario en la página web, el formulario es anadir produccion. 55 Diseño de una aplicación Web para el control de los cultivos frutales Figura 5.2: Formulario anadir produccion 5.5.5.2. Formularios en las vistas Los formularios al igual que muchos elementos en la web deben ser dinámicos, para ello se deben cargar dinámicamente desde las funciones de vistas: from django . s h o r t c u t s import r e n d e r from django . h t t p import H t t p R e s p o n s e R e d i r e c t def c o n t a c t ( r e q u e s t ) : i f r e q u e s t . method == ’POST ’ : form = ContactForm ( r e q u e s t .POST) i f form . i s v a l i d ( ) : # Procesar l o s datos d e l formulario # ... return H t t p R e s p o n s e R e d i r e c t ( ’ / thanks / ’ ) else : form = ContactForm ( ) return r e n d e r ( r e q u e s t , ’ c o n t a c t . html ’ , { ’ form ’ : form , }) En el ejemplo anterior hay tres posibles ramificaciones en el código: 1. Si el formulario no se ha presentado, un formulario vacı́o ContactForm es creado y pasado en la plantilla. 56 Capı́tulo 5. Django 2. Si el formulario ha sido enviado, se crea una instancia que se capta mediante el request.POST. Si el dato presentado es válido, se procesa y el usuario es redirigido a una pagina de agradecimiento (thanks). 3. Si el formulario ha sido enviado pero no es válido, la instancia vacı́a se pasa a la plantilla 5.5.5.3. Formularios sobre modelos Django permite crear formularios directamente sobre modelos, es decir, Django mapea todos los campos del modelo en cuestión y crea un formulario equivalente automáticamente, se hace de la siguiente forma: from django . forms import ModelForm c l a s s A r t i c l e F o r m ( ModelForm ) : c l a s s Meta : model = A r t i c l e 5.5.5.4. Validación La validación de un formulario habitualmente se realiza cuando se llama al método is valid. Por defecto se valida que los datos enviados coincidan con los tipos esperados y los campos obligatorios estén presentes. Se puede personalizar la validación de varias formas: Implementando el método clean() de la clase del formulario: este método permite hacer cualquier validación del formulario que necesite acceder a varios campos. Método clean ¡nombre del campo¿(): este método permite añadir reglas de velicación para un campo concreto del formulario. Implementando el método clean() de una subclase de django.forms.Field : este método es responsable de validar los datos de forma genérica para este tipo de campo. Cualquiera de estos métodos puede lanzar la excepción ValidationError con un mensaje. Si es ası́, la variable cleaned data estará vacı́a y el método is valid retornara False. 57 Diseño de una aplicación Web para el control de los cultivos frutales c l a s s VariedadForm ( forms . Form ) : nombre = forms . C h a r F i e l d ( max length =50) f e c h a i n i = forms . C h a r F i e l d ( l a b e l=” F l o r a c i o n ” , r e q u i r e d=F a l s e ) f e c h a f i n = forms . C h a r F i e l d ( l a b e l=” R e c o l e c c i o n ” , r e q u i r e d=F a l s e ) def c l e a n ( s e l f ) : nombre = s e l f . c l e a n e d d a t a [ ’ nombre ’ ] f f l o r = s e l f . cleaned data [ ’ f e c h a i n i ’ ] f r e c = s e l f . cleaned data [ ’ fecha fin ’ ] if f flor > f rec : r a i s e forms . V a l i d a t i o n E r r o r ( ’ E r r o r en l a s f e c h a s . ’ ) return nombre , f r e c , f f l o r 5.5.6. Contenido Estático Para el correcto funcionamiento una página web hacen falta almacenar archivos estáticos, tales como imágenes, ficheros JavaScript, hojas de estilo CSS, etc. Para ello, Django proporciona una aplicación django.contrib.staticfiles, que gestiona el contenido estático para las aplicaciones y los ordena en una sola ubicación fácil de referenciar y de usar. En el fichero de configuración, settings.py, tenemos unas lı́neas dedicadas al manejo del contenido estático. Existen 4 elementos: STATIC ROOT, STATIC URL, STATICFILES DIRS, STATICFILES FINDERS, cada uno de ellos con un propósito distinto. Hay que prestar especial atención a STATICFILES DIRS. Este elemento permite declarar la ruta, desde la cual se enlazará el contenido estático. Hay que crear un directorio static dentro del directorio del proyecto, para el almacenamiento de este contenido. STATICFILES DIRS = ( ’ /home/ u s e r / a g r o G e s t i o n / s t a t i c / e s t i l o s ’ , ’ /home/ u s e r / a g r o G e s t i o n / s t a t i c / j s ’ , ’ /home/ u s e r / a g r o G e s t i o n / s t a t i c / imagenes ’ , ) 58 Capı́tulo 6 Conclusiones Tras la realización de este proyecto, se han alcanzado la mayorı́a de objetivos pautados inicialmente. Tan solo faltarı́a la aplicación de generar informes sobre producción en distintos años con diferentes variedades que indicará si la empresa tiene beneficios o pérdidas. Personalmente creo que este proyecto ha supuesto un reto a la hora de coger una herramienta de trabajo totalmente desconocida como es Django y poder exprimirla para obtener el resultado deseado. A lo largo del trabajo me he dado cuenta que he adquirido los conocimientos para poder trabajar con cualquier herramienta de programación o lenguaje, es decir, que simplemente leyendo los manuales y visualizando algún ejemplo se puede llegar a realizar un buen trabajo aunque la herramienta usada sea totalmente desconocida hasta el momento. Como trabajos futuros, para que la aplicación pueda tener mucho más potencial se podrı́an mejorar en los siguientes aspectos: Mejora de la interfaz gráfica: la mejora de la interfaz supondrı́a un entorno más sencillo de manejar para el usuario final. Tales mejoras serı́an tanto en el diseño gráfico como en los pequeños detalles, tales como poder ordenar las tablas de resultados de las búsquedas por cualquiera de sus campos, poder realizar búsquedas de un número finito de elementos, etc. Generación de informes: dotar a la aplicación de la herramienta de generación de informes para que el usuario final pudiera extraer ya sea en formato pdf u otro formato, la relación de producción de distintas 59 Diseño de una aplicación Web para el control de los cultivos frutales parcelas a lo largo del tiempo, la relación entre las horas trabajadas y la producción, etc. 60 Apéndices 61 Apéndice A Extracción de datos para aplicaciones externas A.1. Introducción Para hacer posible que se diseñen aplicaciones a partir de este proyecto se ha creado una API (Interfaz de Programación de Aplicaciones), que es un conjunto de funciones y procedimientos que ofrece una biblioteca para ser utilizada con un software externo. Para posibilitar esto se ha desarrollado un script para permitir recopilar datos, por ejemplo para realizar una aplicación móvil, otra web, etc. La API esta desarrollada en PHP, es un ejemplo sencillo pero fácilmente ampliable. A.2. Uso de la API Para usar la API hay que construir una URL con la petición que deseamos hacer. La URL consta de los siguientes parámetros: Dirección del servidor: http://localhost.com:8080/api.php? Parámetros: • getTable: seleccionamos la tabla de la base de datos sobre la que queremos obtener información. • getId: seleccionamos el identificador del elemento de la tabla. Este parámetro requiere getTable. • getCA: seleccionamos la comunidad autónoma de origen del elemento que deseemos buscar. Solo disponible para las tablas parcela 63 Diseño de una aplicación Web para el control de los cultivos frutales y trabajador. Requiere getTable. Las comunidades deben seleccionarse con un código numérico. En la siguiente tabla se muestran los códigos de las distintas comunidades. Código 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 Comunidad Autónoma Andalucı́a Aragón Principado de Asturias Illes Balears Canarias Cantabria Castilla y León Castilla - La Mancha Cataluña Comunitat Valenciana Extremadura Galicia Comunidad de Madrid Región de Murcia Comunidad Foral de Navarra Paı́s Vasco La Rioja Ceuta Melilla Cuadro A.1: Comunidades Autónomas y sus códigos Destacar que los parámetros getID y getCA son incompatibles entre sı́. La construcción de una URL para una petición de un trabajador de Aragón serı́a: h t t p : / / l o c a l h o s t : 8 0 8 0 / a p i / a p i . php? g e t T a b l e=t r a b a j a d o r&getCA=2 A.3. Formato de salida La API retorna los datos en formato XML. A continuación se muestra la salida del ejemplo del apartado anterior: 64 Capı́tulo A. Extracción de datos para aplicaciones externas <?xml version=” 1 . 0 ” e n c o d i n g=” u t f −8” ?> <ag s t a t u s=” ok ”> <t r a b a j a d o r> <i d>22</ i d> <nombre>Huesca</nombre> < a p e l l i d o s>Enrech Enrech</ a p e l l i d o s> <d i r e c c i o n>C/ Mayor 15</ d i r e c c i o n> <m u n i c i p i o i d>22046</ m u n i c i p i o i d> <p r o v i n c i a i d>22</ p r o v i n c i a i d> <cp>22234</ cp> <e m a i l>bergua87@gmail . com</ e m a i l> <t e l e f o n o>974461234</ t e l e f o n o> <d n i>73210145 h</ d n i> <s e x o>V</ s e x o> <c a i d>2</ c a i d> </ t r a b a j a d o r> . . . <t r a b a j a d o r> </ ag> A.4. Código del Script <?php header("Content-type: text/xml"); $user $pass $host $db = = ’root’; = ’asd123’; = ’127.0.0.1:3306’; ’agroGestion’; require_once ’MDB2.php’; $dsn = ’mysql://’.$user.’:’.$pass.’@’.$host.’/’.$db; global $MDB2; $conn=MDB2::connect($dsn); if (PEAR::isError($mdb2)){ echo ($conn->getMessage().’ - ’.$conn->getUserInfo()); } $tabla = $_GET["getTable"]; $id = $_GET["getId"]; $ca = $_GET["getCA"]; $sql = "SELECT * FROM agroWeb_".$tabla; if ($id != ""){ 65 Diseño de una aplicación Web para el control de los cultivos frutales $sql .= " tr WHERE tr.id = ".$id; } if($ca != ""){ if($tabla == "parcela"){ $sql = "SELECT * FROM agroWeb_".$tabla." tr WHERE tr.ca_id = ".$ca; } elseif($tabla == "trabajador"){ $sql = "SELECT * FROM agroWeb_".$tabla." tr, agroWeb_provincia p WHERE tr.provincia_id = p.id AND p.ca_id = ".$ca; } } $result = $conn->query($sql); if(PEAR::isError($result)){ die(’Failed to issue query, error message: ’.$result->getMessage()); } header("Content-type:text/xml"); echo "<?xml version=\"1.0\" encoding=\"utf-8\" ?>"; echo "<ag status=\"ok\">"; while($row = $result->fetchRow(MDB2_FETCHMODE_ASSOC)){ echo "<".$tabla.">"; foreach ($row as $field => $value){ echo "<".$field.">".$value."</".$field.">"; } echo "</".$tabla.">"; } echo "</ag>"; ?> 66 Bibliografı́a [1] SIGPAC, 21-01-2013 http://www.magrama.gob.es/es/agricultura/temas/ sistema-de-informacion-geografica-de-parcelas-agricolas-sigpac-/ [2] GanttProject, 22-01-2013 http://www.ganttproject.biz/ [3] Django Project, 21-01-2013 http://www.djangoproject.com [4] Dia Diagram Editor, 22-01-2013 http://dia-installer.de/ [5] Python, 21-01-2013 http://www.python.org [6] Python Software Foundation, 21-01-2013 http://www.python.org/psf/ [7] PHP, 21-01-2013 http://php.net/ [8] PEAR, 21-01-2013 http://pear.php.net/ [9] HTML, 21-01-2013 http://www.w3.org/ [10] CSS, 21-01-2013 http://www.w3schools.com/css/ [11] JavaScript, 21-01-2013 http://www.w3schools.com/js/ 67 Diseño de una aplicación Web para el control de los cultivos frutales [12] jQuery, 21-01-2013 http://jquery.com/ [13] , 22-01-2013 Lightbox jQuery Plugin http://leandrovieira.com/projects/jquery/lightbox/ [14] UML, 21-01-2013 http://www.uml.org/ [15] MySQL, 21-01-2013 http://www.mysql.com/ [16] XML, 21-01-2013 http://www.w3.org/XML/ [17] , 21-01-2013 LATEX. http://www.latex-project.org/ 68