【问题标题】:Django Nested inline formset-- nested form does not save to DB, no errors thrownDjango嵌套内联表单集-嵌套表单不保存到数据库,没有抛出错误
【发布时间】:2020-06-24 20:17:30
【问题描述】:

我们在应用程序中有一些嵌套的内联表单集。理想情况下,目标是允许这些字段的动态和无限填充,以便用户可以添加任意数量的注释。表单呈现,JS 调用正在填充;但是,我没有看到来自经理的嵌套更新。

这是我的第一个 Django 项目,我没有找到任何关于导致挂起的原因。组织保存在数据库中,但注释没有。

提前感谢您的帮助

模型.py:

class Organization(models.Model):
    //irrelevant organization information//
class OrganizationNote(AbstractNotes):
    note = models.TextField(blank=True)
    org = models.ForeignKey(Organization, on_delete=models.CASCADE,blank=True, null=True)

modelforms.py:

class OrganizationForm(AbstractBigThree):
class Meta:
    model = custModels.Organization
    fields = '__all__'
orgNoteFormSet = inlineformset_factory(custModels.Organization, custModels.OrganizationNote, 
form=OrganizationForm, extra=0)

模型视图.py

class OrganizationCreateView(CreateView, AbstractOrganizationView):

def get(self, request, *args, **kwargs):
    
    self.object = None
    form_class = self.get_form_class()
    form = self.get_form(form_class)
    org_note_form = orgNoteFormSet()
    
    return self.render_to_response(
        self.get_context_data(form=form,
                              org_note_form=org_note_form))

def get_context_data(self, **kwargs):
    data = super(OrganizationCreateView, self).get_context_data(**kwargs)
    if self.request.POST:
        data['notes'] = orgNoteFormSet(self.request.POST)
    else:
        data['notes'] = orgNoteFormSet()
    return data

def form_valid(self, form):
    context = self.get_context_data()
    notes = context['notes']
    with transaction.atomic():
        self.object = form.save()
        if notes.is_valid():
            notes.instance = self.object
            notes.save()
    return super(OrganizationCreateView, self).form_valid(form)

def get_success_url(self):
    return '/portal'

模板:

    {% extends 'base.html' %}
    {% load i18n widget_tweaks %}
    {% block __file__ %}
    <!-- filename == organization_create_form.html -->
    {% endblock %}
    {% block container %}
    <script type="text/javascript">
    $(function() {
        $(".inline.{{ org_note_form.prefix }}").formset({
            prefix: "{{ org_note_form.prefix }}",
    })
    })
    </script>
    <div class="content">
    <div class="thermometer">
        <div style="float:left;padding:10px;">
            <a href="{% url 'index' %}" class="back-link">Dashboard</a>
        </div>
        <div style="float:left;padding:10px;">
            &gt;&gt;<a class="back-link" style="padding-left:10px;"href="">Organization List</a>
        </div>
    </div>

    <div class="col-md-7 main">
        <h1>Create Organization</h1>
        {% if form.errors %}
         {% for field in form %}
        {% for error in field.errors %}
            <div class="alert alert-danger">
                <strong>{{ error|escape }}</strong>
            </div>
        {% endfor %}
    {% endfor %}
            <div id = "form_set">
                <legend>Notes</legend>
            </div>
            <input type="button" value="Add Note" id="add_more">

            <div id="form_set">
                {{ org_note_form.management_form }}
                {{ org_note_form.non_form_errors}}
                {% for form in org_note_form.forms %}
                    {{form.non_field_errors}}
                    {{form.errors}}
                    <table class='no_error'>
                        {{ form }}
                    </table>
                {% endfor %}
            </div>
            <div id="empty_form" style="display:none">
                <table class='no_error'>
                    <fieldset>
                        {{ org_note_form.empty_form}}
                        <div class="inline {{ org_note_form.prefix }}">
                            {{ form.note.errors }}
                            {{ form.note.label_tag }}
                            {{ form.note }}
                        </div>
                    </fieldset>
                </table>
            </div>
            <div>
                <input style="margin-top: 30px;" type="submit" class="btn btn-primary" value="Save" />
            </div>

        </form>

    </div>

</div>    {% endblock %}

    {% block javascripts %}
    <script type="text/javascript">
    
    $('#add_more').click(function() {
        var form_idx = $('#id_form-TOTAL_FORMS').val();
        $('#form_set').append($('#empty_form').html().replace(/__prefix__/g, form_idx));
        $('#id_form-TOTAL_FORMS').val(parseInt(form_idx) + 1);
    });
    </script>
    {% endblock %}

【问题讨论】:

    标签: django formset inline-formset


    【解决方案1】:
    <script> $('#add_more').click(function() {
        var form_idx = $('#id_organizationnote_set-TOTAL_FORMS').val();
        $('#form_set').append($('#empty_form').html().replace(/__prefix__/g, form_idx));
        $('#id_organizationnote_set-TOTAL_FORMS').val(parseInt(form_idx) + 1);
    });</script>
    

    问题已通过编辑模型管理器的前缀得到解决。默认情况下,django 将前缀命名为上面缺少的 table_set。

    【讨论】:

    • 添加related_name='your_field_name' 删除_set 后缀。
    【解决方案2】:

    为您的代码添加另一个选项:

    def form_invalid(self, form):
      print(form.errors)
      ...
    

    要查看表单中是否有任何验证错误,请不要忘记检查内联中的错误

    【讨论】:

    • 不存在错误。前缀不会更新实际的 inlineformset 前缀,因此每条记录都有自己的管理表单。我已经转向使用 django-dynamic-formsets,但即使这样也没有像描述的那样使用。我可以在几分钟内发布更多信息。
    猜你喜欢
    • 2020-06-06
    • 1970-01-01
    • 1970-01-01
    • 2013-11-10
    • 1970-01-01
    • 2012-04-13
    • 1970-01-01
    • 2011-07-27
    相关资源
    最近更新 更多