MultiValueDictKeyError与Django admin中的已修改内联模板

时间:2019-01-10 10:37:15

标签: python django

在Django 1.11中,我有2个模型,FooBar

class Foo(models.Model):
    name = models.CharField()

class Bar(models.Model):
    name = models.CharField()
    foo = models.ForeignKey(Foo)

我的admin.py如下:

class BarInline(admin.StackedInline):
    model = Bar
    template = 'admin/edit_inline/list.html'

class FooAdmin(admin.ModelAdmin):
    fields = ('name')
    inlines = [BarInline]

我使用自定义模板显示Bar内联表单,因为我不希望使用表单,只需链接到每个Bar的编辑页面即可。 list.html看起来像这样:

{% load i18n admin_urls static %}
<div class="js-inline-admin-formset inline-group" data-inline-type="stacked">
<fieldset class="module {{ inline_admin_formset.classes }}">
  <h2>{{ inline_admin_formset.opts.verbose_name_plural|capfirst }}</h2>
{{ inline_admin_formset.formset.management_form }}
{% for inline_admin_form in inline_admin_formset %}<div class="inline-related{% if inline_admin_form.original or inline_admin_form.show_url %} has_original{% endif %}{% if forloop.last %} empty-form last-related{% endif %}">
  <h3 style="overflow:auto"><span style="float:left">{{ inline_admin_formset.opts.verbose_name|capfirst }}:&nbsp;{% if inline_admin_form.original %}<a href="{% url inline_admin_form.model_admin.opts|admin_urlname:'change' inline_admin_form.original.pk|admin_urlquote %}">{{ inline_admin_form.original }}</a>{% else %}#{{ forloop.counter }}{% endif %}</span><span style="float:right">{% if inline_admin_form.original %}<a href="{% url inline_admin_form.model_admin.opts|admin_urlname:'change' inline_admin_form.original.pk|admin_urlquote %}" class="inlinechangelink">Change</a>&nbsp;&nbsp;&nbsp;&nbsp;<a href="{% url 'admin:app_bar_delete' inline_admin_form.original.pk|admin_urlquote %}" class="deletelink">Delete</a>{% endif %}</span>
  </h3>
</div>{% endfor %}
<div class="add-row">
    <a href="{% url 'admin:app_bar_add' %}?foo={{original.pk}}">Add a Bar</a>
</div>
</fieldset>
</div>

问题是,当我编辑现有的Foo并单击Save时,出现错误消息:

  

位于/ admin / app / foo / 1 / change /

的MultiValueDictKeyError      

“'bar_set-0-id'”

编辑:Stacktrace

2 个答案:

答案 0 :(得分:0)

如果您不希望内联表单使用,最简单的方法是不要使字段可编辑。这将使用其值渲染对象,但不能在表单中对其进行编辑。另一种显示方式是admin.TabularInline

内联的选项可以在这里找到; https://docs.djangoproject.com/en/2.1/ref/contrib/admin/#inlinemodeladmin-options

您可能希望启用的选项是show_change_link

您最终会得到类似的东西

class BarInline(admin.StackedInline):
    model = Bar
    fields = ('name', )
    readonly_fields = ('name', )
    show_change_link = True

答案 1 :(得分:0)

对于感兴趣的人,我最终扩展了模板。我在change_form.html中创建了一个文件templates/admin/app/foo/,并覆盖了after_related_objects块:

{% extends 'admin/change_form.html' %}
{% load admin_urls %}
{% block after_related_objects %}
<div class="js-inline-admin-formset inline-group">
    <fieldset class="module">
        {% for bar in original.bar_set.all %}
            <h3>
                {{ bar.name }}
                <a href="{% url 'admin:app_bar_change' bar.pk|admin_urlquote %}">Change</a>
            </h3>
        {% endfor %}
    </fieldset>
</div>
{% endblock %}