【问题标题】:Getting a validation error on filtering inlines on Django Admin在 Django Admin 中过滤内联时出现验证错误
【发布时间】:2017-12-14 10:35:56
【问题描述】:

有一个发票模型和两个定价模型来计算帐单金额。我希望 Django 管理员上的 Invoice 项目的详细信息页面显示唯一一个由 Invoice 模型 (pricing_type) 的属性确定的内联。

为了实现上述目的,我编写了下面的代码,但是当我使用修改后的 pricing_type 在 Django 管理员上保存 Invoice 项目时,它引发了错误(django.core.exceptions.ValidationError: ['ManagementForm data is missing or has been tampered with'])。如何使详细信息页面上的内联可切换?

环境

  • Django 2.0
  • Python 3.6.3

models.py

class Invoice(models.Model):
    pricing_type = models.CharField(
        max_length=1,
        choices=(
            ('A', 'Pricing type A'),
            ('B', 'Pricing type B'),
        ),
        default='A')


class PricingA(models.Model):
    invoice = models.ForeignKey(Invoice, models.CASCADE)


class PricingB(models.Model):
    invoice = models.ForeignKey(Invoice, models.CASCADE)

admin.py

class PricingAInline(admin.TabularInline):
    model = PricingA


class PricingBInline(admin.TabularInline):
    model = PricingB


@admin.register(Invoice)
class InvoiceAdmin(admin.ModelAdmin):
    inlines = [PricingAInline, PricingBInline]

    def get_formsets_with_inlines(self, request, obj=None):
        for inline in self.get_inline_instances(request, obj):
            if isinstance(inline, PricingAInline) and obj is not None and obj.pricing_type == 'A':
                yield inline.get_formset(request, obj), inline
            elif isinstance(inline, PricingBInline) and obj is not None and obj.pricing_type == 'B':
                yield inline.get_formset(request, obj), inline
            continue

【问题讨论】:

  • 您的表单显示方式如何?对于表单集,您还需要在模板中添加managementform
  • 我使用的是默认模板 (admin/edit_inline/tabular.html)。所以我需要通过添加managementform来覆盖它?
  • 默认模板已经定义了{{ inline_admin_formset.formset.management_form }},因此您不必重写它。我建议您查看浏览器开发人员工具中的 HTML,以查看每个内联表单是否具有管理表单的隐藏输入;并检查发布的内容。我现在不知道。

标签: python django


【解决方案1】:

我决定添加一个自定义模板和一个自定义标签来过滤模板级别的内联内容,而不是get_formsets_with_inlines()。它按我的意愿工作。

MY_PROJECT/templates/admin/edit_inline/tabular.html

{% load i18n admin_urls static admin_modify %}
{% load customs %}
<div class="js-inline-admin-formset inline-group" id="{{ inline_admin_formset.formset.prefix }}-group"
     data-inline-type="tabular"
     data-inline-formset="{{ inline_admin_formset.inline_formset_data }}"
     {% visible_inline adminform.form.instance.pricing_type.class_name inline_admin_formset.opts.model %}>

...

MY_PROJECT/MY_APP/templatetags/customs.py

from django import template
from django.utils.safestring import mark_safe

register = template.Library()


@register.simple_tag
def visible_inline(class_name, inline):
    if class_name != inline.__class__.__name__:
        return mark_safe('style="display:none"')

【讨论】:

    猜你喜欢
    • 2012-11-11
    • 1970-01-01
    • 2011-05-17
    • 2014-05-09
    • 2021-09-22
    • 1970-01-01
    • 2011-01-07
    • 2018-12-04
    • 2020-03-01
    相关资源
    最近更新 更多