2012-01-25 6 views
14

He estado escaneando a través de la documentación de Django, y los resultados de búsqueda de Google, toda la tarde y todavía estoy algo atrapado en mi intento de crear un formulario dinámico. Espero que solo necesite que alguien me empuje en la dirección correcta :-) Estoy empezando a aprender Django, así que todavía soy un principiante; sin embargo, ya soy un usuario intermedio de Python.formas dinámicas de Django - ¿población de campo sobre la marcha?

Lo que intento hacer es crear un formulario dinámico, donde el usuario haga una selección de un menú desplegable, y basado en esa selección, otra parte del formulario se actualizará automáticamente para mostrar los resultados relevantes para el actual elemento seleccionado, pero desde otra tabla de base de datos.

Voy a tratar de utilizar una versión simplificada de los modelos de la tutorial de Django para ilustrar mejor lo que estoy tratando de hacer:

# models.py 
from django.db import models 

class Poll(models.Model): 
    question = models.CharField(max_length=200) 

class Choice(models.Model): 
    poll = models.ForeignKey(Poll) 
    choice = models.CharField(max_length=200) 

lo que permite decir que quiero tener algo así como un desplegable abajo del campo de selección, rellenado con la pregunta de cada encuesta en la base de datos. También quiero tener un campo de texto, que muestre las opciones correspondientes para la Encuesta actualmente seleccionada, que se actualizará sobre la marcha siempre que el usuario seleccione una agrupación diferente. Pude resolver esto colocando un botón y volviendo a publicar información en el formulario; Sin embargo, estoy tratando de hacer esto automáticamente a medida que el usuario hace una selección. Mi punto de vista especie de ve algo como esto en la actualidad

#view.py 
from django import forms 
from django.shortcuts import render_to_response 

from myapp.models import Poll,Choice 

class MyModelChoiceField(forms.ModelChoiceField): 
    def label_from_instance(self, obj): 
     return "%s" % obj.question 

class PollSelectionForm(forms.Form): 
    polls = MyModelChoiceField(queryset=Poll.objects.all()) 

class ChoiceResults(forms.Form): 
    def __init__(self, newid, *args, **kwargs): 
     super(ChoiceResults, self).__init__(*args, **kwargs) 

     self.fields['choice'] = forms.TextField(initial="") 

def main(request): 
    return render_to_response("myapp/index.html", { 
     "object": PollSelectionForm(), 
     "object2": ChoiceResults(), 
    }) 

mi plantilla es muy simple, sólo algo así como

{{ object }} 
{{ object2 }} 

Estoy seguro que la forma en que voy sobre la creación de las formas es probablemente tampoco sea el mejor, así que no dude en criticarlo también :-) Como mencioné, he leído soluciones que implican volver a publicar el formulario, pero quiero que esto ocurra sobre la marcha ... si puedo volver a publicar de forma transparente entonces eso estaría bien, supongo. También he visto bibliotecas que te permitirán crear formularios dinámicamente, pero eso simplemente parece exagerado.

+1

Es necesario ajax si quieres que esto suceda de forma automática y sin una actualización del navegador - una vista necesita tomar forma de entrada y responder con contenidos que JavaScript puede leer y reemplazar el elemento html en su formar. –

Respuesta

5

Aquí es uno de los enfoques - Django/jQuery Cascading Select Boxes?

se puede crear una nueva vista que simplemente hace que JSON en una cadena, y luego disparar un evento cuando haya terminado la selección de la primera lista que carga los datos de forma dinámica a partir ese json.

+0

Terminé usando el primer método descrito en el enlace. Se siente como un hack, ya que implica modificar dinámicamente los parámetros de contexto en función de lo que figura en los datos POST y volver a publicar el formulario, pero parecía ser la forma más rápida de llegar a donde necesitaba por el momento. El truco para mí fue crear una función JavaScript simple que envíe tu formulario, y conectarlo a una llamada "OnChange" dentro de mi casilla de selección. Como la solución describe, solo estás recargando esa plantilla con nuevos datos de contexto basados ​​en la información que pasas en POST –

3

Hago una cosa similar aquí, completando un formulario basado en una selección en un menú desplegable. Tal vez esto te ayude.

Aquí es el modelo de los valores utilizados para rellenar previamente la forma:

class OpmerkingenGebrek(models.Model): 
    opmerking = models.CharField(max_length=255) 
    advies = models.CharField(max_length=255) 
    urgentiecodering = models.CharField(max_length=2, choices=URGENTIE_CHOICES_2011) 
    bepaling = models.CharField(max_length=155,blank=True,null=True) 
    aard = models.CharField(max_length=3, choices=AARD_CHOICES) 

La vista que administra la forma:

def manage_component(request,project_id,.....): 
    # get values for pre-populate 
    og = OpmerkingenGebrek.objects.all() 
    ......... 
    formset = ComponentForm(request.POST,request.FILES) 
    ......... 
     ))) 
    return render_to_response(template, { 
     'formset':formset, 
     ........ 
     'og':og, 
     },context_instance=RequestContext(request)) 

El el html hace que la forma

{% extends "base.html" %} 
{% block extra_js %} 
<script type="text/javascript" src="/media/js/limitText.js"></script> 
<script type="text/javascript" src="/media/js/getValueOpmerking.js"></script> 
{% endblock %} 
<form enctype="multipart/form-data" method="post" action=""> 
{{ formset.as_table }} 
</form> 

<p>Choose default values:</p> 
<select id="default" onChange="getValue(this)"> 
    {% for i in og %} 
    <option value="{{ i.opmerking }} | {{ i.advies }} | {{ i.urgentiecodering }} | 
    {{ i.aard }} | {{ i.bepaling }}">{{ i.opmerking }}</option> 
    {% endfor %} 
</select> 

El javascript que rellena previamente el formulario:

función getValue (SEL)

{ 
    //get values 
    var opm = sel.options[sel.selectedIndex].value; 
    //split string to parts 
    var parts = opm.split("|"); 
    // autofill form 
    var opmerking = document.getElementById("id_opmerking"); 
    opmerking.value = parts[0]; 
    var aanbeveling = document.getElementById("id_aanbeveling"); 
    aanbeveling.value = parts[1]; 
    var opt = document.getElementById("id_urgentie"); 
    var urgentie = opt.selectedIndex; 
    for(var i=0;i<opt.length;i++){ 
     if(opt.options[i].value == parts[2].split(' ').join('')){ 
      opt.selectedIndex = i; 
     }}; 

    var opt = document.getElementById("id_aard"); 
    var aard = opt.selectedIndex; 
    for(var i=0;i<opt.length;i++){ 
     if(opt.options[i].value == parts[3].split(' ').join('')){ 
      opt.selectedIndex = i; 
      }}; 

    var bepaling = document.getElementById("id_bepaling"); 
    bepaling.value = parts[4]; 
    }; 
+0

Terminé usando otra solución, pero fue útil ver cómo estás usando javascript para modificar los otros valores de formulario –

Cuestiones relacionadas