2010-11-27 15 views
7

Puse un poco de Javascript del lado del cliente en mi plantilla que permite a un usuario agregar campos dinámicamente a un formulario. Mi problema es que estos campos se limpian en form.cleaned_data, por lo que no puedo acceder a ellos de esa manera.Los campos de formulario agregados dinámicamente se eliminan en form.cleaned_data

Todos los campos están disponibles en request.POST, así que podría resolver este problema con eso, pero quiero hacer esto de la "manera correcta" y creo que la solución está en usar formularios django en lugar de leer la solicitud directamente.

Intenté sobreescribir form.clean(), pero parece que los datos ya se han ido para cuando llegó.

Otros detalles: Estoy nombrando estos campos fieldname_x, donde x es un número. En request.POST, request.POST['fieldname'] es una lista de todos los valores, pero form.cleaned_data contiene solo el último valor de cada lista.

Respuesta

2

¿Sabes qué tipo estos campos van a ser de antemano? ¿Van a ser simples campos de texto? He hecho algo similar a esto, creando formas dinámicas.

# make sure these exist by examining request.POST 
custom_fields = ['fieldname_1', 'fieldname_2'] 

attrs = dict((field, forms.CharField(max_length=100, required=False)) 
      for field in custom_fields) 
DynamicForm = type("DynamicForm", (YourBaseForm,), attrs) 
submitted_form = DynamicForm(request.POST) 

Su formulario enviado ahora debe contener todos los campos que necesita, junto con sus valores. Es posible que desee eliminar required = False, pero eso depende de usted.

Lo que hace esto, es realizar una subclase dinámica de su formulario base, agregando los atributos pasados ​​como atributos a la definición de la clase. Por lo tanto, cuando crea una instancia con datos de publicación, se deben asignar correctamente.

Editar:

leí la pregunta un poco más de cerca. Lo que querrá hacer es asegurarse de que sus elementos de entrada dinámicos tengan el nombre correcto, y los valores se correlacionen con esos nombres de campo una vez que llegue a django. De lo contrario, request.POST no completará el formulario correctamente.

<input type='text' name='fieldname_1' value='value_for_field_1' /> 

etc

0

que estoy haciendo esto en el proyecto Actualmente estoy trabajando. Querrá echarle un vistazo a los conjuntos de formularios. Pero ten cuidado, no es bonito. Tienes que modificar este estúpido campo oculto que almacena en el conteo de formularios, y tienes que cambiar el nombre de las entradas correctamente ... lo que implica una gran cantidad de análisis de cadenas sin sentido. Si se hubieran utilizado matrices, como PHP, no habría un problema, pero están empeñados en hacer la vida imposible ... RAMBLES fuera

Editar: http://docs.djangoproject.com/en/dev/topics/forms/formsets/#empty-form que proporcionan este que hace su vida es un 5% menos dolorosa ... puede hacer un buscar y reemplazar en el prefijo con el número apropiado ... pero creo que tuve un problema donde el formulario vacío no contiene los valores predeterminados correctos si inicializa el formulario con los datos de la publicación, así que tuve que crear una segunda instancia sin datos de la publicación a una empty_form en realidad vacía, que solo está retrasada.

+0

Ralph, sugeriría que usted ha ido en ello el camino más largo. Aproveche Python y el sistema Django de hacer las cosas. Cree dinámicamente modelos y formularios donde sea necesario. Ver mi respuesta –

+0

Su "pitón de apalancamiento" "y Django" están en desacuerdo. Ciertamente has aprovechado la dinámica de Python, pero lo hice de la manera Django. Específicamente pusieron 'empty_form' allí para que pueda usarlo en sus scripts JS y agregar formularios/campos a un formset, así es como lo hice. No es necesario hackear campos adicionales. – mpen

+0

Interpreto la descripción de forma vacía como permitir que javascript agregue formularios adicionales a un formset, no campos adicionales a un formulario. Tú mismo dijiste que la forma en que lo hiciste fue dolorosa, involucró mucho procesamiento de cuerdas y simplemente maldad. Mi solución es 4 líneas de código y es extremadamente fácil de mantener. –

2

También es posible hacer este trabajo en su archivo de formulario, aquí hay una excelente demostración de Jacob Kaplan-Mosse para formas dinámicas: http://jacobian.org/writing/dynamic-form-generation/ que se aplica bastante bien para este problema.

Lo que se hace es agregarle un método para formar una clase que agrega los campos dinámicos adicionales y luego cede la información de la limpieza para que pueda obtenerla en su vista.

class MyForm(forms.Form): 
    text = forms.CharField(max_length=30) 

    def __init__(self, *args, **kwargs): 
     extra = kwargs.pop('extra') 
     super(MyForm, self).__init__(*args, **kwargs) 

     for i, question in enumerate(extra): 
      self.fields['fieldname_%s' % i] = forms.CharField(label=question) 

    def extra_fields(self): 
     for name, value in self.cleaned_data.items(): 
      if name.startswith('fieldname_'): 
       yield (self.fields[name].label, value) 

Y llamarlo desde el punto de vista:

def doSomething(request, extra_fields): 
    form = MyForm(request.POST or None, extra=extra_fields) 
    if form.is_valid(): 
     for (question, answer) in form.extra_answers(): 
      save_answer(request, question, answer) 
     return redirect("create_user_success") 

return render_to_response("template/form.html", {'form': form}) 

muy ordenado, felicidades a Jacob Kaplan-musgo

Cuestiones relacionadas