python django django-widget django-multiwidget

python - Subcontratación de multijugador de Django: reconstrucción de la fecha en la publicación mediante un multwidget personalizado



django-widget django-multiwidget (1)

Así que mi libro de django está de vuelta en la universidad y estoy luchando para solucionar este problema.

He subclasificado 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 ingenioso como tal:

Mi pregunta es muy simple en realidad. Cuando presento dicho formulario a su método de manejo (que utiliza un proceso como este:

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

Esto falla, porque Django no sabe cómo tomar mi multi-widget y convertirlo de nuevo al tipo de campo subyacente, que está establecido en models.py a DateField() , claramente.

Ahora, los comentarios sobre MultiWidget en la fuente de django me dan esta sugerencia útil:

Probablemente querrá usar esta clase con MultiValueField.

Pero la cosa es que probablemente no. Quiero mantener mi DateField() porque es muy útil y no tiene sentido duplicarlo. Lo que tengo que hacer entonces es convertir estos múltiples campos de nuevo en una única fecha de datación válida ( yyyy-mm-dd ) para insertarlos en la base de datos.

Mi pregunta es entonces:

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


Respondí mi propia pregunta!

Implementé 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 extrae los datos de todos los sub-widgets de todo el post datadict. Lo que he hecho es extraer las distintas contrapartes de fecha y usar el constructor de fecha para validar la fecha. Si es válido, imprimimos la cadena en el formato correcto; de lo contrario, devolvemos una cadena vacía que

forminstance.is_valid()

cogerá.

Me encanta cuando hago esto!