2011-01-11 9 views
16

Así que mi libro de Django está de vuelta en la universidad y estoy luchando para trabajar éste hacia fuera.Django subclases multiwidget - fecha en la postal usando la reconstrucción de encargo multiwidget

He subclases django.forms.widgets.MultiWidget así:

class DateSelectorWidget(widgets.MultiWidget): 
    def __init__(self, attrs=None, dt=None, mode=0): 
     if dt is not None: 
      self.datepos = dt 
     else: 
      self.datepos = date.today()  

     # bits of python to create days, months, years 
     # example below, the rest snipped for neatness. 

     years = [(year, year) for year in year_digits] 

     _widgets = (
      widgets.Select(attrs=attrs, choices=days), 
      widgets.Select(attrs=attrs, choices=months), 
      widgets.Select(attrs=attrs, choices=years), 
      ) 
     super(DateSelectorWidget, self).__init__(_widgets, attrs) 

    def decompress(self, value): 
     if value: 
      return [value.day, value.month, value.year] 
     return [None, None, None] 

    def format_output(self, rendered_widgets): 
     return u''.join(rendered_widgets) 

Lo que me da un campo de selección de fecha mirando ingenioso modo: Nifty looking date selection thing

Mi queston es muy simple en realidad. Cuando someter dicho formulario a su método de manipulación (que utiliza un proceso como este:

forminstance = ModelNameForm(request.POST, instance=modelinstance) 
    if forminstance.is_valid(): 
     forminstance.save() 

Esta falla, porque Django no sabe cómo tomar mi multi-widget y convertirlo de nuevo en el tipo de campo subyacente, que se fija en models.py a DateField(), claramente

Ahora, los comentarios de todo el MultiWidget en la fuente de Django me dan este consejo útil:.

Es probable que desee utilizar esta clase con MultiVal ueField.

Pero la cosa es - Probablemente no. Quiero conservar mi DateField() porque es muy útil y no tiene sentido duplicarlo. Lo que tengo que hacer entonces es convertir estos campos múltiples de nuevo en una única cadena de fechas válida (yyyy-mm-dd) para insertarla en la base de datos.

Mi pregunta es:

¿Cómo? ¿Cuál es la mejor manera de lograr esto?

Respuesta

12

Respondió mi propia pregunta!

he implementado este método:

def value_from_datadict(self, data, files, name): 
    datelist = [widget.value_from_datadict(data, files, name + '_%s' % i) \ 
             for i, widget in enumerate(self.widgets)] 
    try: 
     D = date(day=int(datelist[0]), month=int(datelist[1]), \ 
      year=int(datelist[2])) 
     return str(D) 
    except ValueError: 
     return "" 

value_from_datadict tira de los datos de todos los sub-widgets desde el post entero Datadict. Lo que he hecho es extraer las contrapartidas de la fecha y usar el constructor de fecha para validar la fecha. Si es válido es la impresión de la cadena en el formato correcto, de lo contrario, volvemos una cadena vacía, que

forminstance.is_valid() 

cogerá.

¡Me encanta cuando hago esto!

Cuestiones relacionadas