Come ottenere un tag modello per l'auto-check una casella di controllo in Django
-
20-09-2019 - |
Domanda
Io sto usando una classe ModelForm per generare una serie di caselle di controllo per un ManyToManyField ma ho incontrato un problema: mentre il comportamento di default controlla automaticamente le caselle appropriate (quando sto modifica un oggetto), posso' t capire come ottenere che le informazioni nel mio templatetag personalizzato.
Ecco quello che ho nel mio modello:
from myproject.interests.models import Interest
class Node(models.Model):
interests = models.ManyToManyField(Interest, blank=True, null=True)
class MyForm(ModelForm):
from django.forms import CheckboxSelectMultiple, ModelMultipleChoiceField
interests = ModelMultipleChoiceField(
widget=CheckboxSelectMultiple(),
queryset=Interest.objects.all(),
required=False
)
class Meta:
model = MyModel
E a mio avviso:
from myproject.myapp.models import MyModel,MyForm
obj = MyModel.objects.get(pk=1)
f = MyForm(instance=obj)
return render_to_response(
"path/to/form.html", {
"form": f,
},
context_instance=RequestContext(request)
)
E nel mio modello:
{{ form.interests|alignboxes:"CheckOption" }}
Ed ecco il mio templatetag:
@register.filter
def alignboxes(boxes, cls):
"""
Details on how this works can be found here:
http://docs.djangoproject.com/en/1.1/howto/custom-template-tags/
"""
r = ""
i = 0
for box in boxes.field.choices.queryset:
r += "<label for=\"id_%s_%d\" class=\"%s\"><input type=\"checkbox\" name=\"%s\" value=\"%s\" id=\"id_%s_%d\" /> %s</label>\n" % (
boxes.name,
i,
cls,
boxes.name,
box.id,
boxes.name,
i,
box.name
)
i = i + 1
return mark_safe(r)
La cosa è, io faccio solo così posso avvolgere qualche formattazione più semplice intorno a queste caselle, quindi se qualcuno sa come fare che questo accada in un modo più semplice, io sono tutto orecchi. Sarei felice di conoscere un modo per accedere o meno di una scatola dovrebbe essere controllata però.
Soluzione 2
E 'venuto fuori il valore che cercavo, gli elementi della lista che sono stati "controllati" non è nel field
, ma piuttosto parte dell'oggetto form
. I ri-lavorato il tag modello a guardare come questo e lo fa esattamente quello che mi serve:
@register.filter
def alignboxes(boxes, cls):
r = ""
i = 0
for box in boxes.field.choices.queryset:
checked = "checked=checked" if i in boxes.form.initial[boxes.name] else ""
r += "<label for=\"id_%s_%d\" class=\"%s\"><input type=\"checkbox\" name=\"%s\" value=\"%s\" id=\"id_%s_%d\" %s /> %s</label>\n" % (
boxes.name,
i,
cls,
boxes.name,
box.pk,
boxes.name,
i,
checked,
box.name
)
i = i + 1
return r
Per coloro che potrebbero venire dopo, si noti che il valore checked
sopra è stato trovato in boxes.form.initial[boxes.name]
Altri suggerimenti
Nel vostro ingresso per la casella di controllo, si può semplicemente aggiungere il controllare di attributo in base a una certa condizione. Di 'la tua casella di oggetto ha proprietà controllato il cui valore può essere "controllata" o una stringa vuota ""
r += "<label for=\"id_%s_%d\" class=\"%s\"><input type=\"checkbox\" name=\"%s\" value=\"%s\" id=\"id_%s_%d\" %s /> %s</label>\n" % (
boxes.name,
i,
cls,
boxes.name,
box.id,
boxes.name,
i,
box.checked,
box.name
)