Ho un modello di azione che ha una chiave esterna che specifica la frequenza con un'azione ripresenta:Ottenere dati aggiuntivi in Django selezione forma tendina
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")
sto facendo un ModelForm d'azione che si traduce in codice HTML per reoccurance (sulla base dei valori del database che esistono per la tavola 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>
Come si può vedere, anche se le selezioni sono in ordine giorno crescente, i valori sono fuori uso perché sono stati inseriti nella banca dati fuori di ordine.
Desidero creare un jquery che calcoli dinamicamente la data in cui l'azione si ripresenterà. Ci vorrà la data di oggi e aggiungere il numero di giorni che corrispondono alla selezione che l'utente ha scelto. Ma con i dati che ottengo nel modulo, non posso tradurre la selezione in un determinato numero di giorni. Anche se i valori degli elementi di opzione erano in ordine, non indica ancora che "1 anno" è uguale a 365 giorni.
Questi dati si trovano tuttavia nella tabella Reoccurance. Per label = "1 Year", days = 365. Allo stesso modo per tutti gli elementi nella tabella Reoccurance.
C'è un modo per riscrivere il mio modelForm in modo che forse il valore dell'opzione di ogni elemento a discesa sia uguale al numero di giorni per quella selezione? Perché allora, ho potuto accedere al numero di giorni:
$("#id_reoccurance").change(function() {
alert($(this).val());
});
Sarebbe questo influenzare negativamente la mia capacità di legare la selezione reoccurance adeguata alla corretta riga della tabella Reoccurance? C'è un altro modo in cui posso accedere a questo giorno/label tie in jquery sul mio modello di modulo?
Aggiornamento
Grazie al suggerimento di Joseph per controllare this post, sono stato in grado di includere un titolo nel mio elemento opzione:
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)
Fantastic. Così ora ottengo il seguente nel mio modello:
<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, sembra che ci siamo quasi, ma mi sto sgambetto. Nel jquery, sto cercando il seguente per ottenere il titolo dell'opzione selezionata:
$(function() {
$("#id_reoccurance").change(function() {
alert($(this).attr('title'));
});
});
problema è che sta tornando come indefinito!
Aggiornamento Capito
$(function() {
$("#id_reoccurance").change(function() {
alert($(this).find("option:selected").attr("title"));
});
});
io credo che si possa inserire i dati nei campi del modulo attributi nel __init __() del modulo, ma non sono sicuro del metodo esatto per farlo poiché non lo metti solo su un singolo widget di input ma su un numero di elementi