Динамические формы Django - популяция полетов на лету?
Я просматривал документацию по Django и результаты поиска Google, весь день, и я все еще несколько застреваю в попытке создать динамическую форму. Я надеюсь, что мне просто нужно, чтобы кто-то подтолкнул меня в правильном направлении:-) Я только начинаю изучать Django, поэтому я все еще очень начинаю; однако я уже являюсь промежуточным пользователем python.
То, что я пытаюсь сделать, это создать динамическую форму, в которой пользователь делает выбор из выпадающего меню, и на основе этого выбора другая часть формы будет автоматически обновляться, чтобы отображать результаты, относящиеся к выбранному в данный момент, но из другой таблицы базы данных.
Я попытаюсь использовать упрощенную версию моделей из учебника Django, чтобы лучше проиллюстрировать, что я пытаюсь сделать:
# 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)
Итак, скажем, я хочу иметь что-то вроде раскрывающегося поля выбора, заполненного вопросом из каждого опроса в базе данных. Я также хочу иметь текстовое поле, в котором отображаются соответствующие варианты для текущего выбранного опроса, который будет обновляться "на лету" всякий раз, когда пользователь выбирает другой пул. Я смог понять это, разместив кнопку и отправив информацию обратно в форму; Тем не менее, я пытаюсь сделать это автоматически, когда пользователь делает выбор. В настоящее время мой взгляд выглядит примерно так:
#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(),
})
Мой шаблон очень прост, просто что-то вроде
{{ object }}
{{ object2 }}
Я уверен, что способ создания форм, вероятно, тоже не самый лучший, так что не стесняйтесь критиковать это:-) Как я уже говорил, я читал решения, связанные с перепрофилированием формы, но Я хочу, чтобы это произошло "на лету"... если я смогу прозрачно прозрачно, тогда это будет хорошо, я думаю. Я также видел библиотеки, которые позволят вам динамически создавать формы, но это просто кажется излишним.
Ответы
Ответ 1
Вот один из подходов - Каскадные ячейки выбора Django/jQuery?
Вы можете создать новое представление, которое просто выводит json на строку,
а затем инициировать событие, когда вы закончите выбор из первого списка, который динамически загружает данные из этого json.
Ответ 2
Здесь я делаю то же самое, заполняя форму, основанную на выборе в раскрывающемся списке. Возможно, это поможет вам.
Вот модель значений, используемых для предварительного заполнения формы:
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)
Представление, управляющее формой:
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))
html отображает форму
{% 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>
javascript, который предварительно заполняет форму:
function 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];
};