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"));
});
});
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