Django admin error ValidationError: ['ManagementForm data is missing or has been tampered with'] due to conditional inline use
Django admin error ValidationError: ['ManagementForm data is missing or has been tampered with'] due to conditional inline use
我有一个自定义 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, object_id, form_url, extra_context)
我有一个自定义 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, object_id, form_url, extra_context)