[pyar] New-only fields para ForeignKeys en Django admin?

Federico Heinz fheinz en vialibre.org.ar
Lun Feb 21 02:18:56 ART 2011


Enamorado como estoy con el admin app de Django, me he encontrado con
que le falta un feature que sería muy útil: relaciones en las que,
una vez dadas de alta, no se puedan cambiar los extremos.

Para ilustrar de lo que estoy hablando, que creo que es un use
case bastante común, adjunto un zip con un femto-proyecto de juguete,
llamado "pajarones". Tiene dos tablas: una de especies, y una de
colores, y hay una relación de muchos a muchos entre ellas, la idea
es que uno puede decir en ella cuáles especies de pájaros tienen
cuáles colores, y al revés.

Si arrancan el proyecto y van a la URL

<http://localhost:8000/admin/pajarones/species/2/>

Van a ver (ilustrando mi ignorancia en ornitología), que los
guacamayos pueden ser rojos o azules, y verán tres renglones "vacíos"
en la lista de colores, por si quiero agregar más colores posibles
del guacamayo.

Esto está bueno, pero:
  * en realidad, es raro que yo quiera cambiar el color que figura en
    una relación existente. Más cercano a la semántica de la cosa, es
    que, si me equivoqué relacionando el marrón con el guacamayo,
    borre la relación y no le cambie el destino.
  * desde acá puedo ver todos los colores posibles del guacamayo,
    pero si quiero ir a la página de ese color, para ver o corregir
    su información, no tengo una manera de hacerlo directamente.

Sería mejor si el admin usara un <select> para ese campo sólo en los
renglones reservados para nuevas relaciones. En las relaciones ya
existentes, debería mostrar simplemente el __unicode__() del objeto
relacionado, hipervinculado con la página de admin que edita el
objeto.

Jugando un rato, armé un custom widget que hace una parte de esto: en
admin.py está el widget NewOnlySelect, que muestra distintas cosas
dependiendo de si le asignan un valor o no:
  * si no tiene valor, muestra un <select>, tal como antes para que
    el usuario pueda dar de alta una relación
  * si tiene valor, lo mete en un <input type="hidden">,
    y muestra el texto asociado a la selección

Lo pueden ver en acción si, en vez de ver qué colores tienen los
guacamayos, se fijan cuáles especies tienen color rojo
<http://localhost:8000/admin/pajarones/color/2/>

El problema es que me parece que esta técnica no promete mucho más
que esto, porque hay dos cosas que no puede hacer en el caso en el
que tiene un valor:
  1. eliminar el signo "+" en verde al lado del texto, que permite
     dar de alta un objeto en la otra tabla. Ese botón está bueno al
     lado del <select>, pero sin el <select> no tiene sentido
  2. hacer que el texto "Loro" sea un link a la página de admin del
     loro, y que "Guacamayo" haga lo propio con el guacamayo. Para
     eso tendría que construir una URL del tipo
         "http://localhost:8000/admin/pajarones/<clase>/<id>/"
     y si bien el widget sabe cuál es el id (es el valor que le
     asignaron), no tiene idea de cuál es la clase (bueno, en este
     caso sí podríamos hardcodearlo, pero no sirve para el caso
     general).

Se me ocurre que puede haber alguna punta por el lado de usar un form
customizado que use un formfield especial para los foreign keys...
pero no ví nada que sirva para cambiar el formfield que se usa para
"todos los campos de tal tipo", sólo para "tal y cual campo". En
síntesis... BUMP.

¿Alguna sugerencia?

	Fede
------------ próxima parte ------------
A non-text attachment was scrubbed...
Name: pajarones.zip
Type: application/zip
Size: 4358 bytes
Desc: no disponible
URL: <http://listas.python.org.ar/pipermail/pyar/attachments/20110221/454f3eb6/attachment.zip>


More information about the pyar mailing list