Simplifico el url del widget.
Cambio de planes, el parametro do_add ahora es un simple callback que recibe la ID del campo de texto y de la lista
y debe retornar el URL a llamar para obtener los datos (simplificando mucho el manejo del loading y la llamada a JSON).
Del lado del modelo se debe retornar un diccionario con :
* error = True|False : indica si hubo o no error
* msg
- Si error == True el texto de error a mostrar
- Si error == False un diccionario con id y value para el option a agregar de manera que queda
<option value="id">value</option> (si, poco feliz lo de value :P)
AjaxMultiSelect widget generico.
Widget puleta para crear una lista de objetitos para agregar a nuestros objetos.
El widget funciona como un MultipleSelectField con algunos agregados ajaxosos que funcionan out-of-the-box.
Pasa usar el widget el unico requisito es pasar el parametro on_add, que debe ser el nombre de una funcion
javascript que se crea junto con el form (externa al widget y que tiene la logica de validacion prellamada
AJAXosa y la llamada en si).
Ejemplo : en Curso queremos poder agregar la lista de miembros del widget, entonces agregarmos al form lo siguiente :
alumnos = AjaxMultiSelect(name='alumnos', label=_(u'Integrantes'), validator=V.Int(), on_add="alumnos_agregar_a_la_lista")
javascript = [W.JSSource(ajax)]
Definiendo en ajax nuestra funcion como sigue :
function alumnos_agregar_a_la_lista(texto, lista, loading)
{
}
texto contiene el ID (como string) de donde leer el valor a agregar. Lista corresponde al ID de la lista en si y
loading del icono que muestra que se esta haciendo algo.
Para mas detalles como lanzar el JSON y eso ver el ejemplo en Curso.
TODO : hacer que este metodo sea mas facil de implementar :)
Mejorar modelo.
- Agregar varios métodos remove_xxx() correspondientes a los add_xxx().
- Sobrecargar el método set() para objetos con constructor sobrecargado.
- Usar nombres tipo PEP8 en métodos autogenerados.
- Agregar algunas PK que faltaban.
- Agregar algún que otro método add_xxx() que faltaba.
- Agregar algún que otro campo que debería haber estado desde antes (como
CasoDePrueba.privado y CasoDePrueba.activo).
- Eliminar algún que otro JOIN que era copy&paste y no correspondía.
- Tal vez algún fix más.
hago ajaxoso el agregado de alumnos a la lista
por ahora usa el metodo /grupos/de_curso que no deberia estar ahi.
calculo que lo movere a /curso/existe_alumno o algo asi, despues veo
Empiezo a hacer un widget para seleccionar alumnos de forma facil.
La idea es que uno mete padrones y ajaxosamente se valida y si esta ok se agrega a la lista
tambien se pueden borrar y eso. Not big deal todavia, falta lo mas divertido
Remover ByObject.
SQLObject agrega un método getOne() a SelectResult (lo que devuelve el select()
y selectBy), así que ahora en vez de hacer: MySQLObject.by(algo=1), hay
que hacer: MySQLObject.selectBy(algo=1).getOne(). Si el query devuelve más de un
elemento, lanza una excepción SQLObjectIntegrityError. Si se especifica un
default, si no se encontró nada devuelve el default
(A.select(algo=1).getOne(None) devuelve None si no se encontró nada, por
ejemplo), si no lanza un SQLObjectNotFound.
Más info: http://www.sqlobject.org/News.html#id1
Agrego Responsable del curso
Se ingresa solo el padron y el sistema busca que exista el AlumnosInscripto para el curso
seleccionado.
Ademas se agrega un CustomTextField que es un TextField normal con un <span> para ponerle
un mensajito. En este caso se usa para poner el error si no se encontro el alumno o poner
el nombre del Alumno que corresponde al padron.
Hacer que Permiso sea un bit para manejar los permisos como máscaras de bits.
Cada vez que se instancia un Permiso, se le asigna un bit, aumentando la
posición de derecha a izzquierda (es decir, cada vez tiene asignado un entero
más grande). Esto permite hacer muy fácil operaciones lógicas para ver si tiene
varios permisos juntos o si tiene algún permiso de una lista. Además hace que
guardar los permisos en el Rol sea más simple (hay que guardar sólo un entero en
vez de una PickeCol, pero igual la columna Custom todavía no está implementada).
Agregar createSQL al sqlmeta de las clases que necesitan tablas intermedias bizarras.
Hay clases que tienen relaciones ordenadas. Esto no lo permite SQLObject así que
hay que manipular tablas a más bajo nivel, lo que hacía que no se pueda usar el
comando tg-admin sql para crear tablas y otras tareas administrativas. En
SQLObject 0.8 agregan un atributo de sqlmeta (createSQL) que permite agregar SQL
arbitrario al crear las tablas. Se usa esto para crear las tablas intermedias
personalizadas que van por "fuera" de SQLObeject.
Resumen: Si tenés SQLObject 0.8, ahora podés usar tg-admin sql create, por lo
tanto doc/schema/shema.sql está deprecated.
Eliminar constructores redundantes.
Para hacer más conveniente la construcción de objetos se había sobrecargado
todos los constructores de los SQLObjects (parche "Sobreescribe constructores
para que queden m\c3\a1s lindos."). Esto al final traía problemas porque
SQLObjects a veces necesita crear objetos vacíos, así que al final eran
redundantes los constructores, salvo casos excepcionales. Estos casos
excepcionales (generalmente en clases con métodos add_xxx) fueron conservados y
corregidos.
Ahora todos los constructores se llaman al estilo de SQLObject, con todos
keyword arguments.
Completar cambios a Enunciado.
- Se completa el esquema SQL de la DB.
- Se pone como clave (nombre, anio, cuatrimestre) así 2 ejercicios de distintos
cuatrimestres pueden tener el mismo nombre.
- Se corrigen los métodos y constructores que involucran a Enunciado.
Mass upload de alumnos
Podria llegar a faltar una ventanita intermedia que diga que registros se agregaron bien
y cuales mal (por ejemplo si hay algun alumno duplicado)
Actualizar esquema de la DB con cambios de archivo en Enunciado.
Como SQLObject 0.7.x no tiene hooks para hacer cosas extra al crear la DB
(como crear esas tablas intermedias locas que tenemos), no se puede usar
el tg-admin sql create para crear la base, por eso hay que hacerlo via
el script de SQL doc/schema/schema.sql. Por ahora hay que editar ese
archivo a mano cuando se cambia el modelo :S
SQLObject 0.8 (ya está en Debian) agrega hooks para salvar esa
situación, estuve experimentando pero me tira algunos errores, en cuando
lo arregle mando el parche. Además tiene varias mejoras el SQLObject
0.8 así que la idea sería laburar con ese para evitar más hacks.
Arreglar jsonify.
Arreglar tanto jsonificación de clases propias (las pocas que crea
automáticamente TG) y el jsonify_sqlobject() que no soporta
InheritableSQLObjects. Ver ticket #1307:
http://trac.turbogears.org/ticket/1307
Convertir parametros de CasoDePrueba en un campo de string con validador especial.
Guardar los parámetros como una tupla puede ser cómodo pero al usar Pickle, la
base queda ilegible e inusable desde algo que no sea Python. Por lo tanto, y
porque es más natural ingresar los parámetros como un string al estilo bash, se
creó un nuevo tipo de columna de SQLObject que valida/convierte el string
almacenado en una lista y viceversa, permitiendo usar string o listas
indistintamente, pero siempre almacenándose como string.
IMPORTANTE: Hay que regenerar la DB y tiene un "bug", al editar, los datos de la
DB se "renderizan" como una lista en el formulario, hay que ver una forma de
renderizarlo como en el list/show.
Hacer que formularios sean subclase de TableForm.
Si los formularios son instancias de TableForm en vez de subclases, cuando
quieren usar javascript modifican el atributo *de clase* 'javascript' de
TableForm y termina inyectándose el javascript de *todos* los formularios juntos
en cada formulario renderizado. Por ahora no encontré mejor solución que la
subclase.
Agregar controlador para ABM de enunciados.
Controlador para ABM de enunciados. Tal vez se pueda hacer una superclase para
no repetir tanto código, pero como las personalizaciones van a ser cada vez más
frecuentes, no sé si será de mucha utilidad.