Django 管理员错误 ValidationError: ['ManagementForm data is missing or has been tampered with'] 由于有条件的内联使用

问题描述

我有一个自定义User 模型(AbstractUser) 和一个 Stock 模型。假设有多个用户角色 manager,supplier 等。经理可以查看其他经理的详细信息和供应商详细信息

User 模型有一个条件内联,如果用户角色等于 supplier,它会显示每个供应商的库存。(此处角色是一个PositiveSmallIntegerField,有选择和supplier = 2)

class supplierStockInline(admin.StackedInline):
    """ Inline to show stocks of a supplier """

    model = Stock
    extra = 0


@admin.register(User)
class UserAdmin(UserAdmin):
    """ User """

    fieldsets = [
        (None,{'fields': ('username','password')}),('Personal info',{'fields': (
            'first_name','last_name','email',... some custom fields...
        )}),('Permissions',{'fields': (
            'is_active','is_staff','is_superuser','role','groups','user_permissions',)}),('Important dates',{'fields': ('last_login','date_joined')})
    ]

    list_display = [...]
    search_fields = [...]

    # --- the source of the problem ---

    inlines = []

    def get_inlines(self,request,obj):
        """ Show inlines,stocks of supplier """
        try:
            if obj.role == supplier:
                return [supplierStockInline]
        except:
            pass
        return []
    # --- ---- -----

这很好用,直到我尝试将新用户的角色更改为 supplier

ValidationError: ['ManagementForm data is missing or has been tampered with']

该问题是由于重写的 get_inlines() 方法造成的。当我注释掉 get_inlines() 时,它工作正常,而且这只发生在角色 supplier 上。我试图解决这个问题,但无法提出解决方案。

希望得到指导以解决问题,提前致谢。

解决方法

经过数小时的研究,终于找到了 solution,尽管我无法确切解释其发生的原因(可能与没有相关的库存实例有关,并且在更改为角色供应商时突然与库存实例有关系)。

>

无论如何,不​​是覆盖 get_inlines() 方法,而是覆盖 change_view() 并使用条件方法可以解决问题,

class UserAdmin(admin.ModelAdmin):
    ...
    inlines = []

    def change_view(self,request,object_id,form_url='',extra_context=None):
        self.inlines = []
    
        try:
            obj = self.model.objects.get(pk=object_id)
        except self.model.DoesNotExist:
            pass
        else:
            if obj.role == SUPPLIER:
                self.inlines = [SupplierStockInline,]
        return super(UserAdmin,self).change_view(request,form_url,extra_context)