with tutorial para latest framework espaƱol desde cero applications python django django-forms

python - tutorial - latest django



ForeignKey restricciones de forma en Django (5)

"¿Hay alguna forma mejor de hacer esto?" Realmente no. Las jerarquías son difíciles en el modelo relacional. Nada hace más fácil, excepto renunciar por completo a SQL.

"escriba el mecanismo de selección en mi plantilla haciendo un bucle a través de poun_parent_list para obtener las opciones", probablemente no sea óptimo. Esto debería suceder en tu vista.

Estoy usando Django para escribir una aplicación de blog, y estoy tratando de implementar una estructura de categoría jerárquica. Cada categoría tiene un ForeignKey "principal" que apunta nuevamente al mismo modelo de Categoría. Quiero permitir que los administradores agreguen categorías, y quiero que la interfaz les permita seleccionar la categoría principal de una categoría. Sin embargo, quiero evitar situaciones de I''m my own own grandpa, por lo que quiero limitar las opciones disponibles de categorías a aquellas que no tienen una categoría en cuestión como antecesor.

En este momento, estoy controlando esto desde la vista:

parent_candidates = list(Category.objects.all()) pruned_parent_list = [cat for cat in parent_candidates if instance.id not in cat.getHierarchy()]

donde instancia es la categoría que se está editando y getHierarchy () es un método para obtener una lista de identificadores ancestrales.

Hay una serie de problemas con este enfoque. En particular, utiliza un hit de base de datos adicional para obtener la lista de todas las categorías y me hace escribir el mecanismo de selección en mi plantilla haciendo un bucle a través de poun_parent_list para obtener las opciones, cuando realmente prefiero simplemente especificar un widget.

¿Hay alguna forma mejor de hacer esto? Sé que puedo agregar validación personalizada en el back-end para evitar esto, pero ¿por qué darles la opción a los usuarios?


No estoy seguro de si esto es mejor (interacción o no) pero ...

Puede verificar la integridad jerárquica al guardar y generar un error si es necesario.

Idealmente, para este tipo de datos, me gustaría ver un árbol de instancias en el lateral. O al menos el ancestro completo en la vista de detalles del objeto. En ambos casos, ya habrías realizado el viaje extra mencionado en la base de datos.


Si entiendo su problema correctamente, el problema en sí mismo radica en la forma en que se trata de qué categorías pueden ser padres y cuáles no. Una opción para evitar estos problemas es limitar realmente el nivel de categorías que pueden convertirse en padres. Por ejemplo, digamos que tiene las siguientes categorías:

  • Internet
    • Google
    • Yahoo
  • Desconectado
    • MS Office
    • Oficina abierta

La forma en que generalmente manejo esto es que obviamente tengo un FK parent_id en la tabla de categorías. Para los elementos raíz (Internet, fuera de línea), parent_id sería 0. Entonces, cuando en su vista está tratando de recuperar las "categorías principales" para el menú desplegable, debe decidir qué tan lejos pueden seguir anidando. En general, limito esto al primer nivel, por lo que para elegir qué categorías mostrar en tu menú desplegable, harías algo como:

parents = Category.objects.filter(parent_id=0)

Ahora, obviamente, esto limita un poco el enfoque, pero puede aumentar el nivel que desea incluir y elaborar algún tipo de sistema de identificación visual en su plantilla para el menú desplegable (incluidos espacios o guiones adicionales para cada nivel en la jerarquía o algo así )

De todos modos, perdón por la larga respuesta, y espero que esto solucione un poco tu problema.


He tenido que lidiar con categorías de profundidad arbitraria en SQL y parece que no es muy adecuado para almacenar datos de este tipo en una forma normal, ya que las consultas anidadas y / o múltiples JOINs tienden a ponerse feas extremadamente rápido.

Este es casi el único caso donde me gustaría ir con una especie de solución incorrecta, es decir, almacenar categorías en forma de cadena, subcategorías separadas por un delimitador. Hace que tanto las consultas de bases de datos como otras operaciones sean mucho más triviales.

La tabla de categorías se vería así:

id name 1 Internet 2 Internet/Google 3 Internet/Yahoo 4 Offline 5 Offline/MS Office/MS Excel 6 Offline/Openoffice

Otra solución es que, dependiendo de su uso esperado, puede implementar un árbol binario en la lista de categorías. Eso permite seleccionar elegantemente árboles de categorías y relaciones entre padres e hijos. Sin embargo, tiene la limitación de que, al insertar nuevas categorías, se debe volver a calcular el árbol completo, y que conocer el tamaño aproximado del árbol por adelantado es útil.

En cualquier caso, los datos jerárquicos en SQL no son triviales en sí mismos, así que, hagas lo que hagas, probablemente tendrás que hacer bastante codificación personalizada.