渲染Django表格

时间:2018-01-28 22:35:39

标签: jquery ajax django forms

我很难在编辑表格时弄清楚如何在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>

然后使用AJAXmodel字段请求值(在此示例代码中我只返回单个项目):

$('#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调用的视图(出于显示目的,为了在这个问题中保持简单,我在modelsSeries中只有一条记录每个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
  • &#39; 1&#39;是我附加到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> 元素?

2 个答案:

答案 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)

我找到了解释解决方案,其中包含代码示例如何实现链接/依赖下拉列表,巧合的是,在我发布此问题之后,该解决方案就在字面上发布了。

Here's a link.