编辑合并表单和inline_formset的视图

时间:2019-08-01 08:44:02

标签: python django django-forms formset

我一直试图创建一个编辑视图,该视图允许我使用基于文档here

的内联表单集管理父模型和子模型

据我所知,表单集未通过验证。我确实尝试过更改它,以便与其验证整个表单集,不如遍历表单集中的每个单独表单并逐个验证它们。这的确使我可以向表单集中添加项目,但不能删除它们。

此刻,代码导致“未返回HttpResponse对象。而是返回None”值错误,因为重定向在If有效语句中,因此,如果没有得到true,则没有其他重定向到回来。

模型


class Shoppinglist(models.Model):
    name = models.CharField(max_length=50)
    description = models.TextField(max_length=2000)
    created = models.DateField(auto_now_add=True) 
    created_by = models.ForeignKey(User, related_name='lists', on_delete=models.CASCADE)
    last_updated = models.DateTimeField(auto_now=True)

    def __str__(self):
        return self.name

class Item(models.Model):
    name = models.CharField(max_length=80, unique=True)
    amount = models.IntegerField(default=1)
    shoppinglist = models.ForeignKey(Shoppinglist, on_delete=models.CASCADE)

    def __str__(self):
        return self.name

URL


urlpatterns = [
   url(r'^shoppinglists/(?P<pk>\d+)/edit/$', views.shoppinglist_edit, name='shoppinglist_edit'),
]

查看


def shoppinglist_edit(request, pk):

    try:
        shoppinglist = Shoppinglist.objects.get(pk=pk)
    except ShoppingList.DoesNotExist:
        raise Http404

    ItemInlineFormset = inlineformset_factory(Shoppinglist, Item, extra=1, fields=('name', 'amount'))

    if request.method == "POST":
        form = ShoppinglistForm(request.POST, instance=shoppinglist)
        formset = ItemInlineFormset(request.POST, instance=shoppinglist)

        if formset.is_valid() and form.is_valid():
            form.save()
            formset.save()
            return redirect('packlist_list', pk=pk)    

    else:
        form = ShoppinglistForm(instance=shoppinglist)
        formset = ItemInlineFormset(instance=shoppinglist)

        context = {
            'shoppinglist' : shoppinglist,
            'listform': form, 
            'formset': formset,
            }

        return render(request, 'edit_list_with_items.html', context)

模板


{% block content %}
<form method="post">
    {% csrf_token %}

    <label>List Name</label>
    {{ listform.name }}
    {% if listform.first_name.errors %}
        {% for error in listform.first_name.errors %}
            {{ error|escape }}
        {% endfor %}
    {% endif %}

    <label>Description</label>
    {{ listform.description }}
    {% if listform.description.errors %}
        {% for error in listform.description.errors %}
            {{ error|escape }}
        {% endfor %}
    {% endif %}

    {{ formset.management_form }}

    {% for form in formset %}
        <div class="item-formset">
            {{ form.amount }}
            {% if form.amount.errors %}
                {% for error in form.amount.errors %}
                    {{ error|escape }}
                {% endfor %}
            {% endif %}

            {{ form.name }}
            {% if form.name.errors %}
                {% for error in form.name.errors %}
                    {{ error|escape }}
                {% endfor %}
            {% endif %}
        </div>
    {% endfor %}

    {% if formset.non_form_errors %}
        {% for error in formset.non_form_errors %}
            {{ error|escape }}
        {% endfor %}
    {% endif %}

    <div class="row spacer">       
            <button type="submit" class="btn btn-block btn-primary">Create</button>
    </div>
</form>
{% endblock %}

{% block extra_js %}
<script>
  $('.item-formset').formset({
      addText: 'add item',
      deleteText: 'remove'
  });
</script>
{% endblock %}


请注意,我正在模板中使用此jquery插件。

https://github.com/elo80ka/django-dynamic-formset

2 个答案:

答案 0 :(得分:0)

由于您在else块中写入了return render(request, 'edit_list_with_items.html', context),因此出现了提到的错误。

代替此:

else:
        form = ShoppinglistForm(instance=shoppinglist)
        formset = ItemInlineFormset(instance=shoppinglist)

        context = {
            '
            }

        return render(request, 'edit_list_with_items.html', context)

执行以下操作:

else:
        form = ShoppinglistForm(instance=shoppinglist)
        formset = ItemInlineFormset(instance=shoppinglist)

        context = {

            }

return render(request, 'edit_list_with_items.html', context)

答案 1 :(得分:0)

可能是您的表单或表单集无效,并且您没有使用else语句来处理它。

因此在您的 views.py 中:

    if request.method == "POST":
        form = ShoppinglistForm(request.POST, instance=shoppinglist)
        formset = ItemInlineFormset(request.POST, instance=shoppinglist)

        if formset.is_valid() and form.is_valid():
            form.save()
            formset.save()
            return redirect('packlist_list', pk=pk)    
        else:
            # either your form or formset is invalid, so this code will render it again.
            context = {
              'shoppinglist' : shoppinglist,
              'listform': form, 
              'formset': formset,
            }

            return render(request, 'edit_list_with_items.html', context)
    else:
        form = ShoppinglistForm(instance=shoppinglist)
        formset = ItemInlineFormset(instance=shoppinglist)

        context = {
            'shoppinglist' : shoppinglist,
            'listform': form, 
            'formset': formset,
            }

        return render(request, 'edit_list_with_items.html', context)

或者您可以通过以下方式简化它:

    if request.method == "POST":
        form = ShoppinglistForm(request.POST, instance=shoppinglist)
        formset = ItemInlineFormset(request.POST, instance=shoppinglist)

        if formset.is_valid() and form.is_valid():
            form.save()
            formset.save()
            return redirect('packlist_list', pk=pk)    
    else:
        form = ShoppinglistForm(instance=shoppinglist)
        formset = ItemInlineFormset(instance=shoppinglist)
    # notice the indentation
    context = {
        'shoppinglist' : shoppinglist,
        'listform': form, 
        'formset': formset,
    }

    return render(request, 'edit_list_with_items.html', context)