widgets tipos personalizados modelos formularios fields ejemplos avanzados django django-models django-forms

tipos - modelos en django



¿Cómo puedo usar formularios/modelos de django para representar elecciones entre campos? (2)

No estoy del todo seguro de lo que estás haciendo con estos objetos, pero elijas lo que el usuario elija, estarás señalando un solo momento en el tiempo. "Hace 5 días" es "jueves" y viceversa.

Entonces, a menos que las fechas lleguen al sitio (p. Ej., El registro con "5 días atrás" aún significará jueves, mañana, etc.), ¿se trata de un problema de interfaz? Si ese es el caso, me quedaría con un solo valor para la fecha en su Modelo y dejaré que la forma y la vista hagan todo el trabajo.

Eso resuelve el lado del administrador generado automáticamente, ya que solo tendrás un campo con el que competir, pero no te dará la opción de elegir entre los dos a menos que escribas tu propio widget de formulario y anule la clase ModelAdmin para tu modelo.

Si este no es el caso, ignore esta respuesta.

¿Cómo puedo usar opciones booleanas en un campo modelo para habilitar / deshabilitar otros campos? Si un valor booleano es verdadero / falso, quiero que active / desactive otros campos modelo. ¿Hay alguna manera de expresar de forma nativa estas relaciones usando modelos / formularios / widgets django? Sigo escribiendo plantillas personalizadas para modelar estas relaciones, pero no puedo encontrar una buena manera de representarlas en django sin una plantilla especial.

Por ejemplo:

class PointInTime(models.Model): is_absolute_time = models.BooleanField() absolute_time = models.DateTimeField() is_relative_time = models.BooleanField() days_before = models.IntegerField()

Entonces, si is_absolute_time es True, quiero que la entrada absolute_time sea editable en la GUI y que los días antes de la entrada aparezcan en gris y no editables. Si el indicador ''is_relative_time'' es True, quiero que la entrada absolute_time aparezca atenuada y que los días anteriores al valor sean editables. Así que is_absolute_time e is_relative_time serían botones de opción en el mismo grupo en la GUI y sus dos campos correspondientes solo se podrían editar cuando se seleccione su botón de opción. Esto es fácil de hacer en una plantilla personalizada, pero ¿hay alguna manera de usar un modelo / formulario en django para mostrar de forma nativa esta relación?


Sería útil aclarar a qué te refieres con "mostrar de forma nativa esta relación" y pensar claramente sobre la separación de las preocupaciones.

Si todo lo que desea es "atenuar" o deshabilitar un determinado campo en función del valor de otro campo, se trata simplemente de un problema de presentación / IU, por lo que la plantilla (y / o Javascript) es el lugar adecuado para manejarlo.

Si desea validar que los datos enviados son internamente consistentes (es decir, absolute_time se completa si is_absolute_time es True, etc.), se trata de un problema de validación de formulario. El lugar para esa lógica está en el método clean () de su objeto Form o ModelForm.

Si desea asegurarse de que ningún modelo de PointInTime pueda ser guardado en la base de datos sin ser internamente consistente, esa es una preocupación de la capa de datos. El lugar para eso es en un método save () personalizado en su objeto modelo (Django 1.2 incluirá un sistema de validación de modelo más extenso ).

Todas estas opciones implican escribir un código imperativo para hacer lo que necesita con estos campos específicos. Puede ser que esté buscando una forma de representar la situación de manera declarativa en su modelo para que el código en los tres casos anteriores se pueda escribir genéricamente en lugar de específicamente. No hay una forma integrada de Django para hacer esto, pero ciertamente podrías hacer algo como:

class PointInTime(models.Model): field_dependencies = {''is_absolute_time'': ''absolute_time'', ''is_relative_time'': ''days_before''} ... fields here ...

Luego, su código save () modelo (o su código Form clean (), o su plantilla), podría usar este diccionario para determinar qué campos deberían habilitarse / deshabilitarse dependiendo del valor de cuál otro. Sin embargo, esta generalización no vale la pena el esfuerzo, a menos que anticipes tener que hacer lo mismo en una serie de modelos diferentes.

Por último, es posible que desee considerar algunas alternativas de diseño de esquema para normalizar su capa de datos:

  • Si solo hay dos estados válidos (absoluto y relativo), use un único campo booleano en lugar de dos. Entonces evita posibles incoherencias (¿qué significa si ambos booleanos son falsos o verdaderos?)

  • O simplifique aún más eliminando los booleanos por completo y simplemente usando valores nulos en uno u otro de absolute_time / days_before.

  • Si puede haber más de dos estados válidos, utilice un único IntegerField o CharField con opciones en lugar de utilizar dos campos booleanos. La misma razón que la anterior, pero puede acomodar más de dos opciones.

  • Dado que RelativeTime y AbsoluteTime no parecen compartir ningún campo de datos entre sí, considere dividirlos por completo en modelos separados. Si tiene otros modelos que necesitan un ForeignKey para uno u otro, puede modelarlo con herencia (tanto RelativeTime como AbsoluteTime heredan de PointInTime, otros modelos tienen ForeignKeys como PointInTime).