【问题标题】:Django nested formsets adding forms dynamicallyDjango 嵌套表单集动态添加表单
【发布时间】:2018-08-26 02:10:58
【问题描述】:

我正在尝试使用 Django 创建一个调查页面,该页面具有动态添加问题和选择(针对每个问题)的功能。我有以下三个模型类:调查、问题和选​​择。

我做了很多研究来弄清楚如何实现表单,似乎使用 inline_formsets 的嵌套表单集是正确的方法 (I used this tutorial)。但是,我不知道如何使用嵌套表单集动态添加问题和选择。我尝试使用的 JavaScript 库(This library)没有嵌套表单集的示例,我不确定它是否支持它。 这段代码是我目前所拥有的:

forms.py

from django.forms import BaseInlineFormSet
from django.forms import HiddenInput
from django.forms import inlineformset_factory
from django.forms import ModelForm

from .models import *


class SurveyForm(ModelForm):
    class Meta:
        model = Survey
        fields = [
            'name',
            'description',
        ]


class BaseQuestionFormset(BaseInlineFormSet):

    def add_fields(self, form, index):
        super(BaseQuestionFormset, self).add_fields(form, index)
        form.nested = QuestionChoiceFormset(
            instance=form.instance,
            data=form.data if form.is_bound else None,
            files=form.files if form.is_bound else None)

    def is_valid(self):
        result = super(BaseQuestionFormset, self).is_valid()
        print(result)
        if self.is_bound:
            for form in self.forms:
                if hasattr(form, 'nested'):
                    result = result and form.nested.is_valid()

        return result

    def save(self, commit=True):
        for form in self.forms:
            form.save(commit=commit)
        result = super(BaseQuestionFormset, self).save(commit=commit)

        for form in self.forms:
            if hasattr(form, 'nested'):
                if not self._should_delete_form(form):
                    form.nested.save(commit=commit)

        return result


QuestionFormset = inlineformset_factory(
    parent_model=Survey, model=Question, fields='__all__',
    formset=BaseQuestionFormset, extra=1)
QuestionChoiceFormset = inlineformset_factory(
    parent_model=Question, model=Choice,
    fields='__all__', extra=1)

views.py

@login_required
def create(request):
    survey = Survey()
    if request.method == 'POST':
        survey_form = SurveyForm(request.POST, instance=survey)
        question_formset = QuestionFormset(
            request.POST, prefix='questions', instance=survey)

        if survey_form.is_valid() and question_formset.is_valid():
            survey_form.save()
            question_formset.save()
            # url = '/preview/{}'.format(survey.pk)
            # return HttpResponseRedirect(url)
    else:
        survey_form = SurveyForm(instance=survey)
        question_formset = QuestionFormset(instance=survey, prefix='questions')

    context = {
        'survey_form': survey_form,
        'question_formset': question_formset,
    }

    return render(request, 'surveys/create.html', context)

创建.html

{% extends 'surveys/base.html' %}
{% load static %}
{% block container %}
<div class="container">
  <h1> Create New Survey </h1>
  <form method="post">
    {% csrf_token %}
    {{ question_formset.management_form }}
    {{ question_formset.non_form_errors }}
    {{ survey_form.as_p }}
    <table id='myForm1'>
      {% for question_form in question_formset.forms %}
        {{ question_form }}

        {% if question_form.nested %}
          {{ question_form.nested.management_form }}
          {{ question_form.nested.non_form_errors }}
          <div id='myForm2'>
          {% for choice_form in question_form.nested.forms %}
            {{ choice_form }}
          {% endfor %}
          </div>
        {% endif %}
      {% endfor %}
    </table>

    <button type="save">Save</button>
  </form>
</div>
<script src="{% static "surveys/dist/js/jquery.js" %}"></script>
<script src="{% static "surveys/dist/js/jquery.formset.js" %}"></script>
<script type="text/javascript">
  $(function(){
    $('#myForm1').formset({
      prefix: '{{ question_formset.prefix }}',
      formCssClass: 'dynamic-question_formset',
      addText: 'add question'
    });
    $('#myForm2').formset({
      prefix: '{{ choice_form.prefix }}',
      formCssClass: 'dynamic-choice_form',
      addText: 'add choice'
    });
  })
</script>
{% endblock %}

【问题讨论】:

  • 目前的表单显示如何?嵌套问题是在它们出现之前出现还是根本不出现?
  • 我也没有得到fields = '__all__' 参数,有必要吗?是否意味着从某种字段类中获取__all__
  • 表单按预期显示。但是,如果我尝试动态添加问题,它们将不会保存并且我会收到错误消息:['ManagementForm data is missing or has been tampered with'] 并且 Django 需要 inline_formset 的“fields”参数。 'all' 从模型类中获取所有字段

标签: python jquery django-forms nested-forms inline-formset


【解决方案1】:

我最终使用了this plugin!它有嵌套表单集示例的解释。

【讨论】:

  • 你能展示你是如何使用这个库的 - 代码/GitHub等吗?我一直在尝试让演示示例正常工作(主表单、内联表单和嵌套表单都在同一页面上),但它不起作用 - 出错了。也看了这个,也无法让演示运行yergler.net/2009/09/27/nested-formsets-with-django
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-09-12
  • 2020-06-30
  • 1970-01-01
  • 2020-01-22
  • 2013-02-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多