我很难在编辑表格时弄清楚如何在Django表格中更新字段。
在我的表单中,我有一个ModelChoiceField和ChoiceField:第一个是汽车制造商列表,第二个是该制造商可用的型号列表。显然,我不想为每个制造商填充模型的第二个字段,但仅限于第一个ModelChoiceField中选择的模型。
这是我的榜样:
class PostForm(forms.ModelForm):
make = forms.ModelChoiceField(queryset=Manufacturer.objects.all())
model = forms.ChoiceField()
...
要使用表单呈现模板,我使用基于类的视图:
class CreatePost(View):
template_name = 'post/edit_post.html'
def get(self, request):
form = PostForm()
return render(request, self.template_name, {'form': form})
def post(self, request):
form = PostForm(request.POST)
if form.is_valid():
post = form.save(commit=False)
post.owner = request.user
post.save()
return redirect('homepage')
return render(request, self.template_name, {'form': form})
在我呈现PostForm
后的模板中,我使用model
禁用jQuery
字段,并等待用户在make
字段中选择一些值。这是我的模板:
<form class="form-horizontal" action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.non_field_errors }}
{% for field in form %}
<div class="form-group">
<label class="control-label">{{ field.label_tag }}</label>
{{ field }}
{{ field.errors }}
</div>
<div class="form-group">
<button type="submit" class="btn btn-default">Submit</button>
</div>
{% endfor %}
</form>
然后使用AJAX
为model
字段请求值(在此示例代码中我只返回单个项目):
$('#id_make').change(function () {
$.ajax({
url: '{% url 'get_models' %}',
data: {'make': $('#id_make :selected').text()},
dataType: 'json',
success: function (data) {
$('#id_model').append($('<option>', {
value: 1,
text: data.model})).removeAttr('disabled');
}
});
})
这是我用来处理AJAX调用的视图(出于显示目的,为了在这个问题中保持简单,我在models
表Series
中只有一条记录每个manufacturer
并且知道这一点我只查询一条记录。series
是CharField,它保持model
的标题类似于Lancer&#39;对于三菱&#39;制造商):
def get_models(request):
manufacturer = Manufacturer.objects.get(make=request.GET.get('make'))
model = Series.objects.get(make_fk= manufacturer)
return JsonResponse({'model': model.series})
完成此操作后,我会在<select>
的{{1}}元素中看到更新的选项,但在model ChoiceField
选择新值并提交表单后,我会收到:
model ChoiceField
Select a valid choice. 1 is not one of the available choices."
元素然后提交的元素的id。然后我深入挖掘并打印了提交表单的内容,虽然我看到模板中更新了<select>
元素,但在提交的表单I中它仍然是空白的:
<select>
为什么会发生这种情况以及如何更新表单字段本身而不仅仅是<select name="model" class="form-control" id="id_model"></select>
元素?
答案 0 :(得分:1)
目前,您尚未设置model
的任何选项,因此它永远无效。您可以覆盖__init__
方法并在那里设置选项。
您可以将选项设置为所有模型,然后在clean
方法中验证模型是否与make匹配。
class PostForm(forms.ModelForm):
make = forms.ModelChoiceField(queryset=Manufacturer.objects.all())
model = forms.ChoiceField()
def __init__(self, *args, **kwargs):
super(PostForm, self).__init__(*args, **kwargs)
if self.data:
self.fields['model'].choices = ...
def clean(self)
# check that model matches make
由于model
字段引用了series
模型,因此使用ModelChoiceField
并设置self.fields['model'].queryset
可能会更容易。
这只是我头脑中的一个粗略的想法。 tutorial you found使用了类似的方法,但已完整并详细解释。
答案 1 :(得分:0)
我找到了解释解决方案,其中包含代码示例如何实现链接/依赖下拉列表,巧合的是,在我发布此问题之后,该解决方案就在字面上发布了。