我有这个型号:
class QuestionInstance(models.Model):
questionsSet = models.ForeignKey(QuestionsSet)
question = models.ForeignKey(Question)
parent = models.ForeignKey('self',null=True,blank=True)
optional = models.BooleanField(default=False)
我想创建一个下拉列表,用户可以选择一个QuestionInstance。 必须使用questionsSet过滤它。
我已经使用过像这样的模型进行过测试,但它无法正常工作:
(基于此How do I filter values in a Django form using ModelForm?)
class FormQuestionSelect(ModelForm):
instanceList = forms.ChoiceField(choices=[(questionInstance.id, questionInstance.question) for questionInstance in QuestionInstance.objects.all()])
class Meta:
model = QuestionInstance
fields = ('instanceList', )
widgets = {
'instanceList': Select(attrs={'class': 'select'}),
}
def __init__(self, questionsSet=None, **kwargs):
super(FormQuestionSelect, self).__init__(**kwargs)
if questionsSet:
#Tested many code here to filter, None of them worked :(
#Is that possible to create instanceList there ?
我不确定使用模型是出于这种目的的好主意。
创建或更新模型实例时,modelform非常棒。 使用特定表单时,如本例所示,我在模板中使用自定义表单:
查看
questionInstanceList = QuestionInstance.objects.filter(questionsSet=questionsSet)
模板
<select name="questionInstanceSelect">
{% for instance in questionInstanceList %}
<option value="{{ instance.id }}">{{ instance.question.text }}</option>
{% endfor %}
</select>
以这种方式处理它们:
instanceList = request.POST.get('questionInstanceSelect')
我很确定这是一种正确的方法。
答案 0 :(得分:1)
您可以在表单__init__
或视图中更改表单实例化后更改ModelChoiceField的查询集。但这不会解决客户端问题。当有人更改QuestionSet
Question
时,selectbox将保持不变
要更新查询集,只需更新表单字段的一个
form.fields['parent'].queryset = (QuestionInstance.objects
.filter(questionsSet=questionsSet))
或如果您更改表单__init__
self.fields['parent'].queryset = (QuestionInstance.objects
.filter(questionsSet=questionsSet))
但是应该记住,如果在客户端更改questionsSet
,父列表将保持不变。
您是否考虑添加客户端代码更新父选择列表
让我解释一下。
你有模特
class QuestionInstance(models.Model):
questionsSet = models.ForeignKey(QuestionsSet)
question = models.ForeignKey(Question)
parent = models.ForeignKey('self',null=True,blank=True)
optional = models.BooleanField(default=False)
此处父字段链接到self
(相同型号)。
让我们使用“此模型的模型表单”
class FormQuestionSelect(ModelForm):
class Meta:
model = QuestionInstance
ModelForm
将为每个具有相同名称的模型字段创建字段
然后在创建完成后,我们更新ModelChoiceField
(为ForeignKey
创建)queryset
答案 1 :(得分:0)
如果您希望您的字段是动态的,则需要使用jQuery和ajax来实现此功能。我已经给出了在django admin中使用的代码。如果要在自定义页面中使用它,可以稍微调整一下。但这两个概念都是一样的。
(function($){
$(function(){
$(document).ready(function() {
$('#id_questionsSet').bind('change', question_set_change);
$('#id_question > option').show();
if ($('#id_questionsSet').val() != '') {
var question_set_id = $('#id_questionsSet').val();
$.ajax({
"type" : "GET",
"url" : "/product_change/?question_set_id="+question_set_id,
"dataType" : "json",
"cache" : false,
"success" : function(json) {
$('#id_question >option').remove();
for(var j = 0; j < json.length; j++){
$('#id_question').append($('<option></option>').val(json[j][0]).html(json[j][1]));
}
}
});
}
});
});
})(django.jQuery);
// based on the questionsSet, questions will be loaded
var $ = django.jQuery.noConflict();
function question_set_change()
{
var question_set_id = $('#id_questionsSet').val();
$.ajax({
"type" : "GET",
"url" : "/product_change/?question_set_id="+question_set_id,
"dataType" : "json",
"cache" : false,
"success" : function(json) {
$('#id_question > option').remove();
for(var j = 0; j < json.length; j++){
$('#id_question').append($('<option></option>').val(json[j][0]).html(json[j][1]));
}
}
})(jQuery);
}
在views.py中包含以下内容:
import simplejson
from django.shortcuts import HttpResponse
from app.models import Question
def question_choices(request):
question_list = []
question_set_id = request.GET.get('question_set_id')
questions = Question.objects.filter(question_set = question_set_id)
[question_list.append((each_question.pk,each_question.name)) for each_question in questions]
json = simplejson.dumps(question_list)
return HttpResponse(json, mimetype='application/javascript')
在urls.py中:
from app.views import question_choices
urlpatterns = patterns(
(r'^question_set_change/', question_choices),
)
在admin.py中,您要根据question_set加载问题:
class Media:
js = ['/path/to/question_set_change.js',]