2012-09-06 11 views
5

tengo un modelo de actuación que tiene una clave externa que especifica con qué frecuencia se repite una acción:Obtener datos adicionales en la selección Django forma desplegable

class Reoccurance(models.Model): 
    label = models.CharField("Label", max_length=50, unique = True) 
    days = models.IntegerField("Days") 

    def __unicode__(self): 
     return self.label 

    class Meta: 
     ordering = ['days'] 

class Action(models.Model): 
    name = models.CharField("Action Name", max_length=200, unique = True) 
    complete = models.BooleanField(default=False, verbose_name="Complete?") 
    reoccurance = models.ForeignKey(Reoccurance, blank=True, null=True, verbose_name="Reoccurance") 

estoy haciendo una ModelForm de Acción que se traduce en código HTML para reoccurance (basado en los valores de bases de datos que existen para la mesa reoccurance):

<select id="id_reoccurance" class="select" name="reoccurance"> 
    <option value="" selected="selected">---------</option> 
    <option value="12">2 Days</option> 
    <option value="1">3 Days</option> 
    <option value="2">5 Days</option> 
    <option value="10">6 Days</option> 
    <option value="9">1 Week</option> 
    <option value="3">10 Days</option> 
    <option value="4">2 Weeks</option> 
    <option value="11">3 Weeks</option> 
    <option value="5">1 Month</option> 
    <option value="13">6 Weeks</option> 
    <option value="6">1 Quarter</option> 
    <option value="7">6 Months</option> 
    <option value="8">1 Year</option> 
</select> 

Como se puede ver, aunque las selecciones están en orden los días ascendente, los valores están fuera de servicio debido a que se introdujeron en la base de datos a cabo de orden.

Quiero crear un jquery que calcule dinámicamente la fecha en que la acción volverá a ocurrir. Tomará la fecha de hoy y agregará el número de días que corresponden a la selección que el usuario ha elegido. Pero con los datos que obtengo en el formulario, no puedo traducir la selección en un número determinado de días. Incluso si los valores de los elementos de opción estaban en orden, aún no indica que decir "1 año" es igual a 365 días.

Aunque estos datos se encuentran en la tabla Reoccurance. Para label = "1 año", días = 365. Igualmente para todos los elementos en la tabla de recurrencia.

¿Hay alguna manera de volver a escribir mi modelForm para que tal vez el valor de la opción de cada elemento desplegable sea igual al número de días para esa selección? Porque entonces, pude acceder al número de días:

$("#id_reoccurance").change(function() { 
    alert($(this).val()); 
}); 

¿Esto afectará negativamente a mi capacidad de vincular la selección reoccurance adecuada a la fila correcta de la tabla reoccurance? ¿Hay alguna otra manera en la que pueda acceder a esta etiqueta días/etiqueta en jquery en mi plantilla de formulario?

actualización

Gracias a la sugerencia de Joseph para comprobar this post, yo era capaz de incluir un título en mi elemento opción:

from django.utils.html import conditional_escape, escape 
from django.utils.encoding import force_unicode 

class SelectWithTitles(forms.Select): 
    def __init__(self, *args, **kwargs): 
     super(SelectWithTitles, self).__init__(*args, **kwargs) 
     # Ensure the titles dict exists 
     self.titles = {} 

    def render_option(self, selected_choices, option_value, option_label): 
     title_html = (option_label in self.titles) and \ 
      u' title="%s" ' % escape(force_unicode(self.titles[option_label])) or '' 
     option_value = force_unicode(option_value) 
     selected_html = (option_value in selected_choices) and u' selected="selected"' or '' 
     return u'<option value="%s"%s%s>%s</option>' % (
      escape(option_value), title_html, selected_html, 
      conditional_escape(force_unicode(option_label))) 

class ChoiceFieldWithTitles(forms.ChoiceField): 
    widget = SelectWithTitles 

    def __init__(self, choices=(), *args, **kwargs): 
     choice_pairs = [(c[0], c[1]) for c in choices] 
     super(ChoiceFieldWithTitles, self).__init__(choices=choice_pairs, *args, **kwargs) 
     self.widget.titles = dict([(c[1], c[2]) for c in choices]) 

class ActionForm(forms.ModelForm): 
    reoccurance = ChoiceFieldWithTitles() 

    def __init__(self, *args, **kwargs): 
     super(ActionForm, self).__init__(*args, **kwargs) 

     choices = [] 
     for pt in Reoccurance.objects.all(): 
      choices.append((pt.id, pt.label, pt.days)) 
     self.fields['reoccurance'] = ChoiceFieldWithTitles(choices = choices) 

fantástico. Así que ahora me sale el siguiente en mi plantilla:

<select id="id_reoccurance" class="selectwithtitles" name="reoccurance"> 
    <option value="12" title="2" >2 Days</option> 
    <option value="1" title="3" >3 Days</option> 
    <option value="2" title="5" >5 Days</option> 
    <option value="10" title="6" >6 Days</option> 
    <option value="9" title="7" >1 Week</option> 
    <option value="3" title="10" >10 Days</option> 
    <option value="4" title="14" >2 Weeks</option> 
    <option value="11" title="21" >3 Weeks</option> 
    <option value="5" title="30" >1 Month</option> 
    <option value="13" title="42" >6 Weeks</option> 
    <option value="6" title="90" >1 Quarter</option> 
    <option value="7" title="180" >6 Months</option> 
    <option value="8" title="365" >1 Year</option> 
</select> 

Ok, parece que ya casi estamos allí, pero me voy a tropezar. En el jQuery, estoy tratando lo siguiente para obtener el título de la opción seleccionada:

$(function() { 
    $("#id_reoccurance").change(function() { 
     alert($(this).attr('title')); 
    }); 
}); 

problema es que se está volviendo tan indefinido!

actualización Lo tengo

$(function() { 
    $("#id_reoccurance").change(function() { 
     alert($(this).find("option:selected").attr("title")); 
    }); 
}); 
+0

Creo que se puede poner los datos en los campos del formulario atributos en el __init __() del formulario, pero no estoy seguro del método exacto de hacerlo, ya que no solo está poniendo esto en un único widget de entrada, sino en un número de elementos

Respuesta

2

Basando fuera this question/answer (y esto es áspera, no han sido evaluados, es de esperar un comienzo):

class myClassForm(forms.Form): 
    class Meta: 
     model = myClass 
     fields=["name"] 

    reoccurrance = forms.ChoiceField(label="Reoccurance", choices=(), 
            widget=forms.Select(attrs={'class':'selector'})) 


def __init__(self, *args, **kwargs): 
    super(myClassForm, self).__init__(*args, **kwargs) 
    choices = [] 
    for pt in Reoccurance.objects.all(): 
     choices.append((pt.id, unicode(pt.days))) 
    self.fields['reoccurrance'].choices = choices 
+0

Estaba pensando en la misma línea. Pocas cuestiones: quiero que el texto de cada selección sea la "etiqueta". Entonces, en cambio, probé choices.append ((unicode (pt.days), pt.label)).Pero esto me deja con el problema que predije. El modelo espera que el valor de la selección sea igual al ID, no a los días. Por lo tanto, cuando intenta alinear la selección del usuario con el ID en la base de datos, en el mejor de los casos, muestra una discrepancia entre lo que se eligió y lo que se devuelve. En el peor de los casos, dice que no hay entrada desde la tabla de Reocurance que coincida con la selección del usuario (por ejemplo, no hay una identificación que sea igual a 365). –

+1

¿Mira esto? http://stackoverflow.com/questions/5089396/django-form-field-choices-adding-an-attribute – Joseph

+0

¡Genial! ¡¡Gracias!! Esto obtiene los días en la plantilla. Pero ahora, ¿cómo obtengo los días de la opción seleccionada? Ver la revisión anterior. –

Cuestiones relacionadas